web-dev-qa-db-ja.com

C#でGeneric.Listを初期化する

C#では、次の構文を使用してリストを初期化できます。

List<int> intList= new List<int>() { 1, 2, 3 };

{}構文は機能し、名前がある場合。 IEnumerableをとるコンストラクターがあり、それを呼び出すことができます。

List<int> intList= new List<int>(new int[]{ 1, 2, 3 });

それはもっと「標準」のようです。リストのデフォルトコンストラクターを分解すると、

this._items = Array.Empty;

これができるようになりたいです。

CustomClass abc = new CustomClass() {1, 2, 3};

そして、1, 2, 3リスト。これはどのように作動しますか?

更新

ジョン・スキート回答

パラメーターなしのコンストラクターを呼び出してから、Addを呼び出します。

> List<int> tmp = new List<int>();
> tmp.Add(1); tmp.Add(2); tmp.Add(3);
> List<int> intList = tmp;

私は何をするのか理解しています。方法を知りたいです。その構文は、Addメソッドを呼び出すことをどのように知っていますか?

更新

ジョン・スキートの回答を受け入れる決まり文句を知っています。しかし、文字列と整数を使用した例は素晴らしいです。また、非常に役立つMSDNページは次のとおりです。

46
Anthony D

これはcollection initializerと呼ばれます。パラメーターなしのコンストラクターを呼び出してから、Addを呼び出します。

List<int> tmp = new List<int>();
tmp.Add(1);
tmp.Add(2);
tmp.Add(3);
List<int> intList = tmp;

タイプの要件は次のとおりです。

  • IEnumerableを実装します
  • Addのオーバーロードがあり、指定した引数タイプに適しています。中括弧で複数の引数を指定できます。その場合、コンパイラは複数のパラメーターを持つAddメソッドを探します。

例えば:

public class DummyCollection : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new InvalidOperationException("Not a real collection!");
    }

    public void Add(string x)
    {
        Console.WriteLine("Called Add(string)");
    }

    public void Add(int x, int y)
    {
        Console.WriteLine("Called Add(int, int)");
    }
}

次に使用できます:

DummyCollection foo = new DummyCollection
{
    "Hi",
    "There",
    { 1, 2 }
};

(もちろん、通常はコレクションにIEnumerableを適切に実装したいでしょう...)

65
Jon Skeet

読み取りオブジェクトおよびコレクション初期化子(C#プログラミングガイド)基本的には、リストであるすべてのカスタムタイプでこれを実行できます(IEnumerableを実装します)。

7
Cornel

それらは コレクション初期化子here も参照)と呼ばれ、それらの動作方法は、入札が可能なAdd()メソッドを探すことです。中括弧内にある各整数に対してAdd()を呼び出します。

Add()メソッドの検索は、純粋なコンパイラーマジックです。その名前のメソッドを見つけるのはハードコードされています。

4
mqp

探している名前は「Collection Initializer」です。コレクションタイプでAddという名前のメソッドを探し、指定したすべての値に対してそれを呼び出すことにより、内部で機能します。

詳細: オブジェクトおよびコレクションの初期化子(C#プログラミングガイド)

2
JaredPar

.Addメソッドへのショートカットだと思います。ただし、これをオーバーライドしようとしたことはないので、可能かどうかはわかりません。

1
Matt Grande

私に関する限り、オブジェクトの初期化によるアイテムの追加は、Addメソッドを検索します。したがって、List <int>にはvoid Add(int)が含まれるため、機能します。

クラスで使用するには、追加するだけです

class CustomClass { 
   public void Add(int num) {
      // Your code here
   }
}

Hallgrimが指摘したように、クラスはIEnumerableを実装する必要があります。

実際には.Addメソッドを使用しています。つまり、コンストラクター内の括弧内の各アイテムに対して.Addを呼び出しているということです。

0