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 クラスのコンストラクターをオーバーライドできません。MyBaseCollection の代わりに MyRealCollection を渡そうとすることはできません。ジェネリック引数を取り除けば、うまくいきます。MyBaseCollection の代わりに MyRealCollection を使用できます。しかし、コレクション クラスを必要な方法で機能させるには、generics 引数が本当に必要です。

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 に答える