public class A
{
private string _a_string;
public string AString
{
get {开发者_JS百科 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; }
}
}
This does not work:
B _b = new B { A = { AString = "aString" }, BString = "bString" };
System.NullReferenceException : Object reference not set to an instance of an object.
This works:
B _b = new B { A = new A { AString = "aString" }, BString = "bString" };
Both compile fine in VS2010.
The line
B _b = new B { A = { AString = "aString" }, BString = "bString" };
is equivalent to
B _b = new B();
_b.A.AString = "aString"; // null reference here: _b.A == null
_b.BString = "bString";
I think in this form it's clear what's happening.
Compare this with the equivalent form of the expression that works:
B _b = new B();
_b.A = new A();
_b.A.AString = "aString"; // just fine now
_b.BString = "bString";
There is no instantiation of A within B unless you explicitly instantiate it as in your second example.
Change to;
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; }
}
}
To use the first example.
In short, without the new A(), there is no A which is the cause of the NullReferenceException
In the first case, the code is effectively transformed by the compiler into
B b = new B();
A a = b.A;
a.AString = "aString";
b.BString = "bString";
Since you never assigned b.A
to an instance, you get the exception (specifically, since you never assigned b.A
, a
is null and thus a.AString
is going to throw a NullReferenceException
). The fact that nowhere is there code of the form new A...
is a huge clue that an instance of A
is never created.
You could solve this problem by adding A = new A()
to the constructor of B
, or adding a field initializer to B._a
.
In the second case, the code is transformed by the compiler into
B b = new B();
A a = new A();
a.AString = "aString";
b.A = a;
b.BString = "bString";
This is okay, because now we have an instance of A
.
You can't use
A = { AString = "aString" }
because of the same reason you did
B _b = new B {
you must declare an instance of B(and A) in order to use it.
If you would have written
B = B{...
you would get a similar error
精彩评论