public class A
{
private string _a_string;
public string AString
{
get { return _a_string; }
set { _a_string = value; }
}
}
public class B
{
private string _b_string;
private A _a;
public A A
{
get { return _a; }
set { _a = value; }
}
public string BString
{
get { return _b_string; }
set { _b_string = value; }
}
}
这不起作用:
B _b = new B { A = { AString = "aString" }, BString = "bString" };
System.NullReferenceException:对象引用未设置为对象的实例。
这有效:
B _b = new B { A = new A { AString = "aString" }, BString = "bString" };
在VS2010中编译都很好。
答案 0 :(得分:6)
该行
B _b = new B { A = { AString = "aString" }, BString = "bString" };
相当于
B _b = new B();
_b.A.AString = "aString"; // null reference here: _b.A == null
_b.BString = "bString";
我认为在这种形式中,很明显发生了什么。
将其与有效表达式的等效形式进行比较:
B _b = new B();
_b.A = new A();
_b.A.AString = "aString"; // just fine now
_b.BString = "bString";
答案 1 :(得分:4)
除非你在第二个例子中明确地实例化它,否则B中没有A的实例化。
更改为;
public class B
{
private string _b_string;
private A _a = new A();
public A A
{
get { return _a; }
set { _a = value; }
}
public string BString
{
get { return _b_string; }
set { _b_string = value; }
}
}
使用第一个例子。
简而言之,如果没有新A(),则没有 A ,这是NullReferenceException的原因
答案 2 :(得分:1)
在第一种情况下,编译器将代码有效地转换为
B b = new B();
A a = b.A;
a.AString = "aString";
b.BString = "bString";
由于您从未将b.A
分配给实例,因此您获得了异常(具体而言,由于您从未分配b.A
,因此a
为空,因此a.AString
将会扔一个NullReferenceException
)。 事实上,new A...
形式的代码无处可去是一个巨大的线索,即永远不会创建A
的实例。
您可以通过向A = new A()
的构造函数添加B
或向B._a
添加字段初始值设定项来解决此问题。
在第二种情况下,代码由编译器转换为
B b = new B();
A a = new A();
a.AString = "aString";
b.A = a;
b.BString = "bString";
这没关系,因为现在我们有一个A
的实例。
答案 3 :(得分:0)
你不能使用
A = { AString = "aString" }
因为你做了同样的原因
B _b = new B {
您必须声明B(和A)的实例才能使用它。
如果你想写的话
B = B{...
你会得到类似的错误