2009-04-15 21 views
46

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

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のリストを使用できるようにしてください。これはどのように作動しますか?

更新

ジョンスキートは

に答えパラメータなし コンストラクタを呼び出し、その後、追加の呼び出しです:

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

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

更新

私は決まり文句はジョンスキートの答えを受け入れる方法を、知っています。しかし、文字列とintの例は素晴らしいです。また、非常に参考にMSDNのページでは、次のとおりです。

答えて

64

これはコレクション初期化子と呼ばれています。これは、パラメータなしのコンストラクタを呼び出し、その後、追加の呼び出しです:

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

をタイプするための要件は次のとおりです。

  • それはそれはあなたの引数の型に適したAddのオーバーロードがありIEnumerable
  • を実装します供給。複数の引数を中括弧で指定できます。この場合、コンパイラは複数のパラメータを持つ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を実装したいと思います...)

+0

引数が間違った方法だったのを恥ずかしく思っていましたが、今修正されました:) –

+0

なぜ型が列挙可能なのか気になるのですか?それはC#を.NETにもっと気づかせること以外に何も追加していないようです。なぜなら、foreachにはcompatの署名が必要なのはなぜだろうか。 @ lang 'に結び付けられています – meandmycode

+2

@ meandmycode:pre-genericsにはボクシングなしでイテレータを公開する方法が他にないため、foreachはIEnumerableに関連付けられていません。ジェネリックでは、IEnumerable にちょうど*依存していると確信しています。 (続き) –

1

私はそれが.Addメソッドへのショートカットだと信じています。私はそれを無効にしようとしたことは一度もなかったので、可能かどうかはわかりません。

+0

IDictionaryを実装しようとする可能性があります –

0

限り、私は、オブジェクトの初期化を介して項目を追加するとメソッドAddを検索します。したがって、List < int>はvoid Add(int)を持つため、動作します。

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

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

を追加し、あなたのクラスでそれを使用します。

4

これはcollection initializershereも参照)と呼ばれています。その方法は、入札できるAdd()メソッドを探すことです。中括弧内にある各整数に対して、Add()が呼び出されます。

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

+0

「デフォルト」という言葉がどこから得られているかわかりません - 単に「コレクションイニシャライザ」です。 –

+0

十分に公正で、私はそれを変更しました。 – mquander

2

あなたが目を引く名前は「コレクション初期化子」です。これは、コレクションタイプでAddというメソッドを探し、指定したすべての値に対してこのメ​​ソッドを呼び出すことで、フードの下で動作します。

詳細:Object and Collection Initializers (C# Programming Guide)

0

それは実際に.Addメソッドを使用しています。これは、コンストラクタ内の角括弧内の各項目に対して、.Addを呼び出していることを意味します。