约束

时间:2017-04-08 14:06:28

标签: c# generics inheritance generic-programming

我有下面简单的对象模型,其中Manager类包含List Of Child对象,而Child对象必须引用它的父对象:

public class ManagerBase<T1> where T1 : ChildBase<???>
{
    public ManagerBase()
    {
        ChildObjects = new List<T1>();
    }

    public List<T1> ChildObjects { get; set; }
}

public class ChildBase<T1> where T1 : ManagerBase<???>
{
    public ChildBase(T1 parentMgr)
    {
        ParentMgr = parentMgr;
        ParentMgr.ChildObjects.Add(this);
    }

    public T1 ParentMgr { get; set; }
}

以上是BASE课程。现在,下面是继承的样本管理器和子类。我不知道如何使下面的类编译如上所述BASE类尚无效。你能帮忙吗?感谢。

public class CatalogManager : ManagerBase<Catalog>
{
}

public class Catalog : ChildBase<CatalogManager>
{
}

提供更清晰的想法:我有BASE Manager类,BASE Child Object类。有不同类型的继承管理器(CatalogManager,DocumentManager等)和不同类型的子对象(目录,文档等)。现在,每个Manager必须包含List not List。 F.e:带有List的CatalogManager,带List的DocumentManager。同时,每个子对象必须引用它的管理器。换句话说,我需要强类型而不是使用Base类。希望清楚。谢谢你的时间。

1 个答案:

答案 0 :(得分:1)

您可以通过为通用基类创建非泛型基类来实现此目的。更新答案以避免类型转换;为此,ChildObjects属性必须为IEnumerable<T>,因为它的类型参数是协变的,而类IList<T>ICollection<T>是逆变的。

public abstract class ManagerBase
{
    protected ManagerBase()
    {
        innerChildObjectList = new List<ChildBase>();
    }
    private IList innerChildObjectList;
    public IEnumerable<ChildBase> ChildObjects
    {
        get
        {
            foreach (ChildBase child in innerChildObjectList.OfType<ChildBase>())
                yield return child;
        }
    }
    public void AddChild<T>(T child) where T : ChildBase
    {
        innerChildObjectList.Add(child);
    }
    public void RemoveChild<T>(T child) where T : ChildBase
    {
        innerChildObjectList.Remove(child);
    }
    public bool ContainsChild<T>(T child) where T : ChildBase
    {
        return innerChildObjectList.Contains(child);
    }
    //Add 'Insert', 'RemoveAt' methods if needed.
}
public abstract class Manager<T>
    : ManagerBase
    where T : ChildBase
{
    public new IEnumerable<T> ChildObjects
    {
        get { return base.ChildObjects.OfType<T>(); }
    }
}
public abstract class ChildBase
{
    protected ChildBase(ManagerBase mgr)
    {
        ParentMgr = mgr;
    }
    private ManagerBase parentMgr;
    public ManagerBase ParentMgr
    {
        get { return parentMgr; }
        set
        {
            if (parentMgr != null && parentMgr.ContainsChild(this))
                parentMgr.RemoveChild(this);
            parentMgr = value;
            parentMgr.AddChild(this);
        }
    }
}
public abstract class Child<T>
    : ChildBase
    where T : ManagerBase
{
    protected Child(T mgr) : base (mgr)
    {
    }
    public new T ParentMgr
    {
        get { return base.ParentMgr as T; }
        set { base.ParentMgr = value; }
    }
}

现在可以了:

public class CatalogManager : Manager<Catalog>
{
}

public class Catalog : Child<CatalogManager>
{
    public Catalog(CatalogManager parentMgr) : base(parentMgr)
    {

    }
}