[英]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.