4

C# 3 では、初期化子が追加されました。これは素晴らしい機能です。ただし、1 つのことが私を混乱させます。

クラスを初期化するときは、通常、初期化するメンバー変数またはプロパティを指定する必要があります。例えば:

class C { public int i; }

public void blah() {
    C c = new C() { i = 1 };
}

配列のセマンティクスは最初から C# にあったと思います。しかし、彼らはそのように振る舞いません。例えば

public void foo()
{
    int[] i = new int[] { 0, 1, 2, 3 };
}

すべて問題ありませんが、配列セマンティクスを持つクラスはどうでしょうか?

public void bar()
{
    List<int> li = new List<int>() { 0, 1, 3, 3 };
}

List は、他のものと同様に単なるクラスです (ジェネリックですが)。

コンパイラが List メンバーを初期化する方法を理解しようとしています。これは舞台裏で行われるある種の魔法ですか?それとも、これはクラスで定義されたインデクサーがあることに関連していますか?

ありがとう。

4

2 に答える 2

9

C#言語仕様v3.0セクション7.5.10.3コレクション初期化子:

コレクション初期化子が適用されるコレクションオブジェクトは、実装するタイプである必要があります。そうでないSystem.Collections.IEnumerable場合、コンパイル時エラーが発生します。指定された要素ごとに、コレクション初期化子はAdd、要素初期化子の式リストを引数リストとしてターゲットオブジェクトのメソッドを呼び出し、呼び出しごとに通常の過負荷解決を適用します。したがって、コレクションオブジェクトには、Add各要素の初期化子に適用可能なメソッドが含まれている必要があります。

独自のコレクションでこの機能を有効にするには、Add適切なパラメーターを持つメソッドが必要です。Addコンパイラーは、指定した引数を使用して、メソッドへの一連の呼び出しに変換します。

于 2009-09-05T03:52:30.937 に答える
2

私のやや限定的な理解からすると、List はコレクション初期化子と呼ばれる別のセマンティックを使用します。それが違いの原因かもしれません。

于 2009-09-05T03:43:35.680 に答える