2012-05-08 16 views
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を渡すことはできません。ジェネリックの議論を取り除くと、それは機能します。 MyRealCollectionはMyBaseCollectionの代わりに受け入れられます。しかし、コレクションクラスを必要な方法で動作させるためには、ジェネリックの議論が本当に必要です。

+0

C#4を使用している場合この質問と回答を参照してください。問題への直接的な答えではないかもしれませんが、少しコードをリファクタリングすることになると助けになるかもしれません:http://stackoverflow.com/q/9203352/250725 – psubsee2003

答えて

3

のインスタンスに渡されていた場合は、完全MyBaseObjectの観点から法的ではなくなるだろうと私は示唆しますあなたは反共と共分散を調べます。 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> 
{ } 
+2

+1。具体的には、 'IEnumerable 'でこれを行うことができます。これは、Tが 'out'型のパラメータとして定義されているからです。インタフェース上での演算の出力としてのみ使用されるため、外部の力で干渉することはできません。私の答えの例で) –

+0

@Chris +1、明確化のためにありがとう。 – Squirrelsama

+1

これの鍵は、私の実際のプロジェクトが使用しているインタフェースを使用することでした。この例では単純化していますが、コレクションのTジェネリックをそのまま宣言しています。 – Random

3

MyBaseCollectionは、のコレクションであり、MyBaseObjectではなく、MyBaseCollectionの代わりに使用できません。なぜの考え方については、MyBaseObjectのコンストラクタは、このやった場合を想像:

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

をあなたは MyRealCollection

関連する問題