为什么这个嵌套对象初始值设定项抛出空引用exception?

以下测试用例在尝试将Id分配给null的对象时抛出空引用exception,因为代码在对象初始值设定项之前缺少“new R”。

为什么这不会被编译器捕获? 为什么允许这样,用例会是一个有意义的构造?

[TestClass] public class ThrowAway { public class H { public int Id { get; set; } } public class R { public H Header { get; set; } } [TestMethod] public void ThrowsException() { var request = new R { Header = { Id = 1 }, }; } } 

编译器不会发出警告,因为您可以:

 public class R { public H Header { get; set; } public R() { Header = new H(); } } 

所以Header可以由某人/某事初始化。 解决是否某人/某事将初始化Header是一个复杂的问题(可能类似于Halting问题)…不是编译器想要为你解决的问题:-)

从C#规范:

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

我们是嵌套初始化器的情况,并看到粗体部分。 我不知道。

现在,请注意,根据C#规范, new R { }7.6.10.1 Object creation expressions后跟object-initializer ,而Header = { }是“纯” 7.6.10.2 Object initializers