数组初始值设定项在编译时有效,但在对象初始化程序内部运行时失败

时间:2016-08-10 12:24:49

标签: c# .net clr

在使用对象初始化程序时,我试图通过数组初始化程序错误地实例化ICollection(我忘记了new ...部分)。有点奇怪的是,编译器在编译时没有抱怨,而是在运行时遇到了NullReferenceException。

以下是一些总结情况的代码:

public class FakeClass
{
    public ICollection<string> StringsCollection { get; set; }

    public string[] StringsArray { get; set; }
}

FakeClass c = new FakeClass();
c.StringsCollection = { "test" }; // doesn't compile - ok
c.StringsCollection = new string[] { "test" }; // compiles - ok
c.StringsArray = { "test" }; // doesn't compile - ok
c.StringsArray = new string[] { "test" }; // compiles - ok

string[] strings = { "sdfqgrt" }; // compiles - ok
strings = { "sdfqgrt" }; // doesn't compile - ok

FakeClass c2 = new FakeClass
{
    StringsCollection = { "rthtj" }, // compiles and throws at run - why?
    StringsArray = { "egryjt" } // doesn't compile - ok
};

当然我理解为什么这段代码无法运行,但我很好奇编译器如何接受这样的事情。

1 个答案:

答案 0 :(得分:2)

StringsCollection = { "rthtj" }

此代码没有任何问题。它调用隐式Add方法并将字符串添加到集合中。

NRE除外,因为您的财产尚未初始化。

这将有效

 public ICollection<string> StringsCollection { get; set; } = new List<string>();

更新以回复评论

对于此代码

FakeClass c = new FakeClass();
c.StringsCollection = new string[] { "test" }; 

FakeClass c2 = new FakeClass
{
    StringsCollection = { "dd" }
};

查看IL并注意第一个和第二个StringCollection

之间的差异

IlSpy

对于setter案例,您需要使用new string[] {}或新{4}}案例的表达式来使用集合初始值设定项。