0

次のクラスがあるとします。

class Master {
  int x;
  int y;

  public int X { get { return x; } set { x = value; } }
  public int Y { get { return y; } set { y = value; } }
}

class Sub1:Master {
  int z;

  public int Z { get { return z; } set { z = value; } }
}

class Sub2:Master {
  int w;

  public int W { get { return w; } set { w = value; } }
}
class Sub3:Master {
  int t;

  public int T { get { return t; } set { t = value; } }
}

Sub*次に、タイプごとに 1 つずつ、3 つの異なる配列を定義しました。

List<Sub1> array1;
List<Sub2> array2;
List<Sub3> array3;

最後に、統一された方法ですべてのインスタンスにアクセスする方法が必要です。アイデアは、新しい配列List<T>[] array4 = new[] {array1, array2, array3};を使用し、インデックスとして使用することでした。そのため、プロパティとintの一般的な操作の 3 倍を記述する必要はありません。XY

ただし、3 つの配列の型が異なるため、この方法では実行できません。何を使用できますか?

4

3 に答える 3

1

これらは基本タイプを共有するため、List<Master>3つのタイプすべてのインスタンスを保持するを作成できます。

最終的に、すべてのオブジェクトは同じ基本タイプを共有するobjectため、常に持つことができますList<object>が、この場合、オブジェクトは階層の上位にある基本タイプを共有するため、を使用できますMaster

すべてのインスタンスのリストを作成するには、次のようにします。

var all = new List<Master>(array1.Count + array2.Count + array3.Count);

all.AddRange(array1);
all.AddRange(array2);
all.AddRange(array3);

最初に新しいリストを作成し、予想される容量がわかっているので、を受け入れるコンストラクターのオーバーロードを使用しますint capacity。このように、他のコレクションを追加するときにリストのサイズを変更する必要がないため、コードがより効率的になります。

ちなみに、これはおそらくサンプルコードにすぎないことはわかっていますが、変数の名前は変数が表すものに応じてarray*指定する必要があるため、実際に配列を表す場合は、のような名前を付ける必要があります。

于 2012-07-10T21:25:32.483 に答える
0

Listは非ジェネリックインターフェイス、、を実装しているICollectionためIEnumerableIList次の新しい配列を作成できます。IList[] array4 = { array1, array2, array3 };

または、リストに要素を追加するときに、次のように、マスタータイプの別のリストに要素を追加することもできます。

List<Sub1> array1 = new List<Sub1>();
List<Sub2> array2 = new List<Sub2>();
List<Sub3> array3 = new List<Sub3>();
List<Master> array4 = new List<Master>();

...

public void AddSub1(Sub1 sub)
{
    array1.Add(sub);
    array4.Add(sub);
}

public void AddSub2(Sub2 sub)
{
    array2.Add(sub);
    array4.Add(sub);
}

public void AddSub3(Sub3 sub)
{
    array3.Add(sub);
    array4.Add(sub);
}

このようにして、array4のすべての要素を反復処理できます。

foreach(Master master in array4)
{
   master.DoSomething();
}
于 2012-07-10T21:33:04.633 に答える
0

IEnumerable<T>として宣言されIEnumerable<out T>、実装する のランタイムタイプにEnumerable.ElementAt<T>最適化されているという事実を使用して、実際にこれを機能させることができます。これにより、次のことが可能になります。IEnumerable<T>IList<T>

var x = new IEnumerable<Master>[] {array1, array2, array3};
x[0].ElementAt(4);

リストの個々の要素への一定時間のアクセスを取得しながら。少しぎこちなく感じますが、それでも機能するはずです。

実行中の作業に適合する場合、私の意見では、より良いオプションは、ジェネリック メソッドを作成し、各リストでジェネリック メソッドを呼び出すことです。

private void MainMethod()
{
    List<Sub1> array1 = new List<Sub1>();
    List<Sub2> array2 = new List<Sub2>();
    List<Sub3> array3 = new List<Sub3>();
    DoOperation(array1);
    DoOperation(array2);
    DoOperation(array3);
}

private void DoOperation<T>(List<T> list) where T: Master
{
    // do work here
    list[0].X = 0;
}
于 2012-07-10T23:01:23.347 に答える