2

私が持っていると仮定します:

class A {
  //field, properties and common methods
}

class B : A {
  //specific ones
}

class C : A {
  //specific ones
}

class D : A {
  //specific ones
}

そして、これらの 3 つのリスト:

List<B> b_list = new List<B>();
List<C> c_list = new List<C>();
List<D> d_list = new List<D>();

b_listc_listおよびを指すリストが必要d_listです。クラス B、C、D が同じスーパークラス A を持っていると考えることは可能ですか?

何かのようなもの:

List<A>[] lists = new[] {b_list, c_list, d_list};

ありがとうございました

4

4 に答える 4

2

List<B>List<C>、およびList<D>を のサブクラスとして扱いたいのですList<A>が、そうではありません。それらの唯一の共通のスーパータイプはobject.

.NET 4 以降では、インターフェイスが で共変でIEnumerable<A>あるため、これらの型をすべて に参照変換できます。.NET 4.5 では、さらに 2 つの共変インターフェイス と が追加されたため、これらを およびとして扱うこともできます。これらのインターフェースのいずれかがニーズに合う場合があります。IEnumerable<out T>TIReadOnlyList<out T>IReadOnlyCollection<out T>IReadOnlyList<A>IReadOnlyCollection<A>

.NET ではクラスを共変にすることはできません。型パラメーターが "出力" 位置でのみ使用される場合、インターフェイスはその型パラメーターでのみ共変にすることができます。言い換えれば、この方法は共変になるIList<T>.Add(T item)ことを防ぎIList<>ます。

したがって、.NET 4.5 を想定して、これを行うことができます。

IReadOnlyList<A>[] lists = new[] {b_list, c_list, d_list};

.NET 4 では、これを行うことができましたが、これはあまり役に立ちませんが、ニーズには十分かもしれません。

IEnumerable<A>[] lists = new[] {b_list, c_list, d_list};
于 2012-10-05T23:26:51.070 に答える
1

A のリストのリストを作成し、それに b、c、d オブジェクトを割り当てる必要があります。サブクラス オブジェクトを親クラス A にキャストする必要があります。これにより制限が発生し、基本クラスから継承されたプロパティやメソッドなどにのみアクセスすることになります。

List<B> blist = new List<B>();
List<C> cList = new List<C>();
List<D> dList = new List<D>();

List<List<A>> arrays = new List<List<A>>();    
arrays.Add(b_array.ConvertAll(c=>(A)c));;
于 2012-10-05T22:56:15.683 に答える
1

直接ではない(共分散「制限」)

しかし、あなたはすることができます

List<A> superTypeList = 
   b_array.Cast<A>()
   .Concat(c_array.Cast<A>())
   .Concat(d_array.Cast<A>())
   .ToList();
于 2012-10-05T23:00:58.057 に答える
0

より良いアプローチは、複合パターンと呼ばれる設計パターンを使用することです。

基本的に、子ノード (子ノードがある場合は Compisites ノード、分岐が停止した場合はリーフ ノード) に必要なすべてのメソッドを含む基本クラス (コンポーネント) を作成し、それぞれに必要なメソッドのみを実装します。各子タイプで使用します。

あなたの場合、これを行うかもしれません:

abstract class A {   
    //All methods for all classes
    //ex.
    public abstract void b();
    public abstract void c();
    public abstract void d();
}  

class B : A {   
    public override void b()
    {
        //Do Something
    }
    public override void c()
    {
        throw new Exception("Not Implemented");
    }
    public override void d()
    {
        throw new Exception("Not Implemented");
    }
}  

class C : A {   
    public override void b()
    {
        throw new Exception("Not Implemented");
    }
    public override void c()
    {
        //Do Something
    }
    public override void d()
    {
        throw new Exception("Not Implemented");
    }
}  

class D : A {   
    public override void b()
    {
        throw new Exception("Not Implemented");
    }
    public override void c()
    {
        throw new Exception("Not Implemented");
    }
    public override void d()
    {
        //Do Something
    }
}

次に、ポリモーフィズムの法則に従って、次のようなことを行うと、派生クラス (b、c、d など) のメソッドを保持する必要があります。

List<B> blist = new List<B>(); 
List<C> cList = new List<C>(); 
List<D> dList = new List<D>();  
List<List<A>> arrays = new List<List<A>>();
于 2012-10-05T23:42:28.320 に答える