我有一个半复杂的继承结构,我在覆盖基类的构造函数时遇到了困难。以下代码可以显示错误:
public abstract class MyBaseObject
{
public MyBaseObject(MyBaseCollection<MyBaseObject> parent)
{
this.Parent = parent;
}
public MyBaseCollection<MyBaseObject> Parent { get; set; }
}
public abstract class MyBaseCollection<T>
where T : MyBaseObject
{ }
public class MyRealObject : MyBaseObject
{
public MyRealObject(MyRealCollection parent)
: base(parent)
{ }
public new MyRealCollection Parent { get { return (MyRealCollection)base.Parent; } }
}
public class MyRealCollection : MyBaseCollection<MyRealObject>
{ }
因此,具体来说,我无法覆盖MyBaseObject类中的构造函数。试图传入MyRealCollection代替MyBaseCollection是不可接受的。如果我摆脱了泛型论证,它就可以了;接受MyRealCollection代替MyBaseCollection。但我真的需要泛型参数来使我的集合类以我需要的方式工作。
答案 0 :(得分:3)
MyBalCollection不接受MyRealCollection,因为它是MyRealObject
的集合,而不是MyBaseObject
。为了解原因,想象一下MyBaseObject的构造函数是否这样做:
public MyBaseObject(MyBaseCollection<MyBaseObject> parent)
{
this.Parent = parent;
parent.Add(new SomeOtherRealObject());
}
从MyBaseObject
的角度来看,这是完全合法的,但如果你传入MyRealCollection
答案 1 :(得分:3)
我建议你研究逆变和协方差。这可能是一个好的开始http://msdn.microsoft.com/en-us/library/dd799517.aspx
简而言之,CLR无法假设您希望它对类型继承采取什么假设,因为某些非常明确的原因超出了我的工资等级。
但是,如果您稍微使用类型层次结构,则可以执行此类操作。我使用IEnumerable来帮助。
public abstract class MyBaseObject
{
public MyBaseObject(IEnumerable<MyBaseObject> parent)
{
this.Parent = parent;
}
public IEnumerable<MyBaseObject> Parent { get; set; }
}
public class MyRealObject : MyBaseObject
{
public MyRealObject(MyRealCollection parent)
: base(parent)
{ }
public new MyRealCollection Parent { get { return (MyRealCollection)base.Parent; } }
}
public class MyRealCollection : IEnumerable<MyRealObject>
{ }