简体   繁体   English

C#泛型类型在哪里约束

[英]c# generic type on where constraint

I have below simple object model where Manager class consist List Of Child objects and Child object must have reference to it's parent object: 我在下面的简单对象模型中,其中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; }
}

Above are BASE classes. 以上是BASE类。 Now, below are inherited sample Manager and Child classes. 现在,下面是继承的示例Manager和Child类。 I don't know how to make below classes to compile as above BASE classes are not valid yet. 我不知道如何使下面的类进行编译,因为上面的BASE类还无效。 Could you pls help? 您能帮忙吗? Thanks. 谢谢。

public class CatalogManager : ManagerBase<Catalog>
{
}

public class Catalog : ChildBase<CatalogManager>
{
}

To provide more clear idea: I have BASE Manager class, BASE Child Object class. 为了提供更清晰的想法:我有BASE Manager类,BASE子对象类。 There are different type of inherited Managers (CatalogManager, DocumentManager etc.) and different type of Child Objects (Catalog, Document etc). 有不同类型的继承管理器(CatalogManager,DocumentManager等)和不同类型的子对象(Catalog,Document等)。 Now, each Manager must consist of List not List. 现在,每个管理器必须由列表而不是列表组成。 Fe: CatalogManager with List, DocumentManager with List. Fe:带列表的CatalogManager,带列表的DocumentManager。 At the same time, each child object must have reference to it's Manager. 同时,每个子对象都必须引用其管理者。 In other words, I need strong typing instead of using Base classes. 换句话说,我需要强类型化而不是使用基类。 Hope it clear. 希望清楚。 Thanks for your time. 谢谢你的时间。

You can achieve that by creating non-generic base classes for the generic base classes. 您可以通过为通用基类创建非通用基类来实现。 Answer updated to avoid type casting; 答案已更新以避免类型转换; to do so, ChildObjects property had to be IEnumerable<T> because it's type parameter is covariant, while classes, IList<T> , and ICollection<T> are contravariant. 为此, 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; }
    }
}

Now this will be okay: 现在这可以了:

public class CatalogManager : Manager<Catalog>
{
}

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

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM