.net 4.0中的继承对象的主子对象设计和通用基类型

时间:2017-07-07 17:38:01

标签: c# generics inheritance

I need to 2 levels of inheritance and abstraction in master-child relationship是讨论的开始。

我想要的是确保来自BaseMaster的所有继承对象必须包含子列表,并且子类型必须从BaseChild继承。根据那篇文章,我已将我的设计确定为

public abstract class BaseMaster<TChild> where TChild : BaseChild
{
    public Collection<TChild> Children { get; }
}

public abstract BaseChild
{ }

public class FirstRealMaster : BaseMaster<FirstRealChild> { /* add more properties */ }

public class FirstChild : BaseChild { /* add more properties */ }

但是使用这样的设计我失去了使用基础对象类型来描述继承对象的能力,因为不允许BaseMaster<BaseChild> b = new FirstRealMaster();,技术上有不同的类型。以下是一个示例代码我希望我能使它发挥作用。

    static BaseMaster<BaseChild> ReturnBaseMaster(int i)
    {
        if (i == 1)
        {
            return new FirstRealMaster();
        }
        else if (i == 2)
        {
            return new SecondRealMaster();
        }

        return null;
    }

这种限制造成了很多不便。这里有任何建议如何改进设计以实现我的目标,即我需要对象模型来强制所有继承的类来生成子项。同时我仍然希望灵活地为继承类型使用基类型?

1 个答案:

答案 0 :(得分:1)

我不确定你要求的是什么,但也许这符合你的期望:

using System.Collections.Generic;

namespace ConsoleApplication
{
    class Program
    {
        static void Main (string[] args)
        {
            IMaster<IChild>           master1 = new ConcreteMaster ();
            IMaster<BaseChild>        master2 = new ConcreteMaster ();
            IMaster<ConcreteChild>    master3 = new ConcreteMaster ();
            BaseMaster<ConcreteChild> master4 = new ConcreteMaster ();
        }
    }

    public interface IChild { }

    public interface IMaster<out T> where T : IChild
    {
        IReadOnlyList<T> Children { get; }
    }

    public abstract class BaseMaster<T> : IMaster<T> where T : IChild
    {
        private readonly List<T> children = new List<T> ();

        public IReadOnlyList<T> Children => children;

        public void Add (T child)
        {
            children.Add (child);
        }
    }

    public abstract class BaseChild : IChild { }

    public class ConcreteMaster : BaseMaster<ConcreteChild> { }

    public class ConcreteChild : BaseChild {  }
}

请注意,如果您想要添加子项,则需要使用基类型。