列表属性的初始化程序语法

Eri*_*c B 5 c#

在使用List作为属性初始化类时,我目睹了一些奇怪的事情.这样做的时候

var stuff = new Stuff(){list = {1, 2, 3} };
Run Code Online (Sandbox Code Playgroud)

它编译,崩溃说列表为空.所以,将它添加到Stuff的构造函数中:

public Stuff(){
    list = new List<int>();
}
Run Code Online (Sandbox Code Playgroud)

列表现在已初始化为包含{1, 2, 3}似乎有意义的内容.但是,然后将构造函数更改为

public Stuff(){
    list = new List<int>(){1, 2, 3};
}
Run Code Online (Sandbox Code Playgroud)

并初始化如此

var stuff = new Stuff(){list = {4, 5, 6} };
Run Code Online (Sandbox Code Playgroud)

list被初始化为包含{1, 2, 3, 4, 5, 6}让我感到困惑.

这似乎不应该编译,或者不应该这样做.到底发生了什么?

Ree*_*sey 3

看起来这要么不应该编译,要么不应该以这种方式运行。这里究竟发生了什么?

集合初始值设定项通过调用.Add传递到初始值设定项的每个项目上的方法来工作。这会将它们添加到您在构造函数中预先填充的项目中。

集合初始值设定项的文档对此进行了解释:

集合初始值设定项允许您在初始化实现 IEnumerable 的集合类时指定一个或多个元素初始值设定项。元素初始值设定项可以是简单值、表达式或对象初始值设定项。通过使用集合初始值设定项,您不必在源代码中指定对类的 Add 方法的多次调用;编译器添加调用。

这意味着编译器会将您的第二次调用转换为类似于以下内容的内容:

var temp = new Stuff();
temp.list.Add(4);
temp.list.Add(5);
temp.list.Add(6);
Stuff stuff = temp;
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,该stuff变量将正常调用构造函数(添加123),然后添加其他项,从而得到您所看到的结果。