为什么这个C#赋值会抛出异常
本文关键字:抛出异常 赋值 为什么 | 更新日期: 2023-09-27 18:00:47
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" };
系统。NullReferenceException:对象引用未设置为对象的实例
这项工作:
B _b = new B { A = new A { AString = "aString" }, BString = "bString" };
两者都在VS2010中编译良好。
行
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";
除非像第二个例子中那样显式实例化,否则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
在第一种情况下,编译器将代码有效地转换为
B b = new B();
A a = b.A;
a.AString = "aString";
b.BString = "bString";
由于从未将b.A
分配给实例,因此会得到异常(特别是,由于从未分配b.A
,a
为null,因此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
的一个实例。
您不能使用
A = { AString = "aString" }
因为和你做的原因一样
B _b = new B {
您必须声明B(和A(的实例才能使用它。
如果你会写
B = B{...
您会得到类似的错误