我有一个抽象基类
class AbstractClass
{
Col<AbstractClass> parent
public AbstractClass()
{
//do stuff
}
}
我有两个实现
class A : AbstractClass
{
Col<A> parent
public A(Col<A> parent)
:base(parent)
{
this.parent = parent;
}
}
class B : AbstractClass
{
Col<B> parent
public B(Col<B> parent)
:base(parent)
{
this.parent = parent;
}
}
我有一个集合
class Col<T> : IList<T> where T : AbstractClass
哪个将在Col<A> and Col<B>
的其他课程中使用,让我们称这个班级为C
。
class C
{
List<A> a = new List<A>()
List<B> b = new List<B>()
}
除了我希望类型A
和B
知道他们的父集合之外,这一切都有效。我认为在AbstractClass
中有以下构造函数,A,B可以,但似乎泛型约束只适用于类而不适用于方法。基本上我想要以下构造函数:
public AbstractClass(Col<T> where T : AbstractClass)
public A(Col<A>)
public B(Col<B>)
A,B的实例需要知道它们所处的集合,但是我不能从派生类中调用基础构造函数,因为它们是不同的类型。
帮助!
答案 0 :(得分:4)
当我想做这样的事情时,我经常使用与C ++ curiously recurring template pattern相关的模式:
abstract class AbstractClass<TDerivedClass>
where TDerivedClass : AbstractClass<TDerivedClass>
{
Col<TDerivedClass> parent;
public AbstractClass(Col<TDerivedClass> parent)
{
// do stuff
this.parent = parent;
}
}
class A : AbstractClass<A>
{
public A(Col<A> parent)
:base(parent) {}
}
class B : AbstractClass<B>
{
public A(Col<B> parent)
:base(parent) {}
}
答案 1 :(得分:1)
我希望类型A和B知道他们的父集合
您可能对this article感兴趣。我用XML序列化编写了它,但它可以在更一般的上下文中使用
答案 2 :(得分:1)
使用自定义Collection<T>
类型而非List<T>
。它们基本上提供相同的功能(Collection<T>
在内部使用List<T>
),并且正是出于此目的。
然后,您可以覆盖InsertItem
以设置添加到集合中的任何项目的父级。
public class MyCollection<T> : System.Collections.ObjectModel.Collection<T>
{
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
item.Parent = this;
}
}
答案 3 :(得分:0)
据我了解,这不能在C# 2.0 中完成。该功能已经位于CLR中,但C#不允许这样做。在C#2.0中,我们有不变的泛型。在C#4.0中,将支持方差。
以下是我的参考资料:
http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx
http://code.msdn.microsoft.com/csharpfuture
http://channel9.msdn.com/pdc2008/TL16/
我是对的吗?