请考虑以下代码:
class Data
{
public string Name;
public string NameWithSufix;
}
class Behaviour
{
private Data data;
public string Name { get { return data.Name; } private set { } }
public Behaviour()
{
data = new Data()
{
Name = "My Name",
NameWithSufix = Name + " Sufix",
};
//data = new Data();
//data.Name = "My Name";
//data.NameWithSufix = Name + " Sufix";
}
}
class Program
{
static void Main(string[] args)
{
Behaviour behaviour = new Behaviour();
}
}
如果运行此程序,它将在Name属性中失败并显示NullReferenceException。 This和this回答和Visual Studio试图说服我对象初始化器和对象构造函数后跟属性赋值是相同的,但它似乎不是这样。如果我用注释代码交换构造函数的主体,它就可以工作。在尝试分配属性之前,似乎initiliazer实际上并没有运行构造函数。为什么呢?
答案 0 :(得分:4)
Name
中的{p> NameWithSufix = Name
指向data.Name
,当时data
为空。对象初始化器的更好表示是:
Data d = new Data();
d.Name = "My Name";
d.NameWithSufix = this.data.Name /*Name*/ + " Sufix"; // <-- see the problem here
this.data = d;
在对象初始化程序完成之前,请注意this.data
未设置。
如PetSerAl所述,C# language specification支持这一点。
答案 1 :(得分:3)
它首先运行Behavior
构造函数。问题是Data
类的初始化尚未完成,因此以下引用会引发异常
NameWithSufix = Name + " Sufix",
因为此时调用get { return data.Name; }
但data
仍为null
。
的更新强> 的
Patrick Hofman在他的回答中说得更好更准确 - 并不是Data
类的初始化不完整,而是新实例尚未分配给{{1变量。
此外,he requested a clarification to the official docs - 如果您同意,请竖起大拇指。