c#:简单的多重继承/混合替换

本文关键字:混合 替换 多重继承 简单 | 更新日期: 2023-09-27 18:16:23

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

由于c#既不支持混合也不支持多重继承,那么解决这个问题的常用方法是什么?
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的字段数量相当高(并且在开发阶段它们变化很大)。


是否有最佳实践?

c#:简单的多重继承/混合替换

将这些类的实例聚合到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和私有setter的自动实现属性。

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

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

创建一个从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
    }
}