sur*_*ace 3 c# object-initializers curly-braces
Whille为WPF/MVVM项目的集合创建了一些虚拟数据,我生成了以下错误代码,编译得很好,但在运行时抛出异常.
有一个嵌套的数据对象结构,我错误地只用花括号进行实例化(看起来像编写JavaScript确实会对大脑造成永久性损害).
using System.Collections.ObjectModel;
namespace testapp
{
class Program
{
static void Main(string[] args)
{
var collection = new ObservableCollection<TopLevelDataObject>();
collection.Add(new TopLevelDataObject{Nested = {Bar = 5}}); // NullReferenceException
}
class TopLevelDataObject
{
public NestedDataObject Nested { get; set; }
public string Foo { get; set; }
}
class NestedDataObject
{
public double Bar { get; set; }
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么要编译?
如果我创建一个匿名类型,比如Nested = new {Bar = 5},我在编译期间收到错误消息(因此失败):
Cannot implicitly convert type '<anonymous type: int Bar>' to 'testapp.Program.NestedDataObject'
Run Code Online (Sandbox Code Playgroud)
为什么在省略new运算符时没有出现这样的错误?
它甚至为我提供了该属性的代码提示:

我的猜测就是这{Bar = 5}只是一个代码块,它本身就是一个有效的东西.但为什么将代码块分配给任何东西(在这种情况下,Nested属性)是有效的?
为什么要编译?
因为在编译代码时,它只被编译为一组赋值操作.它并非都是您创建的新实例.
如果Nested从构造函数构造新实例,则可以为其分配值Nested.Bar.
更改public NestedDataObject Nested { get; set; }为此以查看其工作原理:
public NestedDataObject Nested { get; } = new NestedDataObject();
Run Code Online (Sandbox Code Playgroud)
(注意,您永远不能Nested在上面的代码中将值赋给构造函数外部!)