在初始化列表中分配readonly属性

可以告诉我,为什么它会编译?

namespace ManagedConsoleSketchbook { public interface IMyInterface { int IntfProp { get; set; } } public class MyClass { private IMyInterface field = null; public IMyInterface Property { get { return field; } } } public class Program { public static void Method(MyClass @class) { Console.WriteLine(@class.Property.IntfProp.ToString()); } public static void Main(string[] args) { // ************ // *** Here *** // ************ // Assignment to read-only property? wth? Method(new MyClass { Property = { IntfProp = 5 }}); } } } 

这是一个嵌套的对象初始化器 。 它在C#4规范中描述如下:

在等号后面指定对象初始值设定项的成员初始值设定项是嵌套对象初始值设定项 – 即嵌入对象的初始化。 而不是为字段或属性分配新值,而是将嵌套对象初始值设定项中的赋值视为对字段或属性成员的赋值。 嵌套对象初始值设定项不能应用于具有值类型的属性,也不能应用于具有值类型的只读字段。

所以这段代码:

 MyClass foo = new MyClass { Property = { IntfProp = 5 }}; 

相当于:

 MyClass tmp = new MyClass(); // Call the *getter* of Property, but the *setter* of IntfProp tmp.Property.IntfProp = 5; MyClass foo = tmp; 

因为您使用的是使用ItfProp的setter的初始化ItfProp而不是 Property的setter。

因此它将在运行时抛出NullReferenceException ,因为Property仍然为null

因为

 int IntfProp { get; set; } 

不是只读。

你没有调用MyClass.Property setter,只是getter。