C#:simple多继承/ mixin替换?

时间:2015-10-06 19:12:49

标签: c#

我有一个来自外部库的类,我需要将其扩展到antoher类。此外,扩展应保持可重用,因为我还需要在其他地方实现扩展。

由于C#中既不支持mixins也不支持多重继承,常用方法解决这个问题是什么?

namespace ExtLib
{
    public class Properties
    {
        public virtual int fieldN { get; set; }
    }
}

namespace MyLib
{
    public class Extensions
    {
        public virtual int fieldM { get; set; }
    }
}

namespace MyProject
{
    public class MyModel
    {
        // needs to have all fields from ExtLib.Properties AND MyLib.Extensions
    }

    public class MyOtherModel
    {
        // needs to have all fields from MyLib.Extensions,
        // MyLib.Extensions should be reusable
    }
}

我知道解决方案可能是一个接口IExtensions,但由于ExtensionsProperties字段的数量非常高(并且在开发中),这会导致很多重复阶段他们改变了很多)。

有没有最佳做法?

2 个答案:

答案 0 :(得分:6)

您如何将这些类的实例聚合到MyModel

public class MyModel
{
    private Properties _properties;
    private Extensions _ extensions;

    public MyModel(Properties properties, Extensions extensions)
    {
        _properties = properties;
        _extensions = extensions;
    }

    public Properties Prop
    {
        get { return _properties; }
    }

    public Extensions Ext
    {
        get { return _extensions; }
    }
}

或者,您当然可以摆脱手动支持字段,并使用公共getter和私有设置器自动实现的属性。

PropertiesExtensions的所有更改都会自动反映在MyModel中。聚合是以面向对象的方式使用设计模式的常用方式,而不是类方式,它经常使用多重继承。

对于多态性问题,您可以创建派生类,覆盖您想要的任何行为,并将该类的实例传递给构造函数。

答案 1 :(得分:0)

创建一个派生自ExtLib的抽象类,然后从抽象类派生MyProject

namespace ExtLib
{
    public class Properties
    {
        public virtual int fieldN1 { get; set; }
        public virtual int fieldN2 { get; set; }
        public virtual int fieldN3 { get; set; }
        public virtual int fieldN4 { get; set; }
        public virtual int fieldN5 { get; set; }
    }
}

namespace MyLib
{
    abstract class Extensions : Properties
    {
        public virtual int fieldM1 { get; set; }
        public virtual int fieldM2 { get; set; }
        public virtual int fieldM3 { get; set; }
        public virtual int fieldM4 { get; set; }
        public virtual int fieldM5 { get; set; }
    }
}

namespace MyProject
{
    public class MyModel : Extensions
    {
        // contains all fields from ExtLib.Properties AND MyLib.Extensions
    }
}