3

我有一个半复杂的继承结构,我在覆盖基类上的构造函数时遇到了困难。以下代码可以显示错误:

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 被接受。但是我真的需要泛型参数来使我的集合类按照我需要的方式工作。

4

2 回答 2

3

不接受 MyRealCollection 代替 MyBaseCollection,因为它是 的集合MyRealObject,而不是MyBaseObject。想知道为什么,想象一下 MyBaseObject 的构造函数是否这样做:

public MyBaseObject(MyBaseCollection<MyBaseObject> parent)
{
    this.Parent = parent;
    parent.Add(new SomeOtherRealObject());
}

从 的角度来看,这将是完全合法的MyBaseObject,但如果您通过了MyRealCollection

于 2012-05-08T17:08:47.200 回答
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>
{ }
于 2012-05-08T17:12:26.753 回答