2

このコードを実行するThisIsAListと、期待どおりに空のコレクションに初期化されません...代わりThisIsAListにnullでした。

void Main()
{
    var thing = new Thing
    {
        ThisIsAList = {}
    };

    Console.WriteLine(thing.ThisIsAList == null); // prints "True"
}

public class Thing
{
    public List<string> ThisIsAList { get; set; }
}

なぜこれはコンパイルエラーではないのですか? 結果はなぜnullですか?


ここで暗黙の変換が行われているのではないかと思っていましたが、次の試行でコンパイル エラーが発生しました。

thing.ThisIsAList = Enumerable.Empty<string>().ToArray();
List<int> integers = { 0, 1, 2, 3 };

コレクション初期化子に関するMSDNのドキュメントによると、コレクション初期化子は基本的に呼び出しAdd()を処理するだけのようです。そこで、 への可能なオーバーロードを探しましたがList.Add、適用できると思われるものは見つかりませんでした。

誰かがここで何が起こっているのかを C# 仕様から説明できますか?

4

1 に答える 1

7

C# 5.0仕様のセクション7.6.10.2:

等号の後にコレクション初期化子を指定するメンバー初期化子は、埋め込みコレクションの初期化です。フィールドまたはプロパティに新しいコレクションを割り当てる代わりに、初期化子で指定された要素がフィールドまたはプロパティによって参照されるコレクションに追加されます。フィールドまたはプロパティは、§7.6.10.3 で指定された要件を満たすコレクション型である必要があります。

(私のものを強調)

したがって、コレクション初期化子は別のオブジェクト/コレクション初期化子の内部にネストされているため、初期化するメンバーを値に解決してから、関連するアイテムを追加するという動作になります。この場合、プロパティはnullであるため、null値が解決され、初期化子のすべてのゼロ項目が追加されます。実際にアイテムを追加しようとすると、アイテムをnullオブジェクトに追加しようとするため、NRE がスローされます。

于 2015-05-06T18:30:50.883 に答える