2

当我运行这段代码时,它并没有ThisIsAList像我期望的那样初始化为一个空集合……而是ThisIsAList为空。

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值被解析,并且初始化器中的所有零项都被添加。如果你真的试图添加一个项目,它会抛出一个 NRE,因为你试图向一个null对象添加一个项目。

于 2015-05-06T18:30:50.883 回答