问题
I just noticed that the following is possible in C# written in Visual Studio 2015, but I've never seen it before:
public class X
{
public int A { get; set; }
public Y B { get; set; }
}
public class Y
{
public int C {get; set; }
}
public void Foo()
{
var x = new X { A = 1, B = { C = 3 } };
}
My expectation was for Foo to have to be implemented like this:
public void Foo()
{
var x = new X { A = 1, B = new Y { C = 3 } };
}
Note that there is no need to call new Y
.
Is this new in C# 6? I haven't seen any mention of this in the release notes, so maybe it's always been there?
回答1:
You will get a NullReferenceException if you run this code.
It will not create an instance of Y
, it will call the getter of X.B
property and try to assign value to property C.
It always worked like that. According to C# 5.0 language specification:
A member initializer that specifies an object initializer after the equals sign is a nested object initializer, i.e. an initialization of an embedded object. Instead of assigning a new value to the field or property, the assignments in the nested object initializer are treated as assignments to members of the field or property.
回答2:
This feature was introduced in C# 3.0 as object initializers.
See example on p. 169 of C# Language 3.0 specification:
Rectangle r = new Rectangle {
P1 = { X = 0, Y = 1 },
P2 = { X = 2, Y = 3 }
};
which has the same effect as
Rectangle __r = new Rectangle();
__r.P1.X = 0;
__r.P1.Y = 1;
__r.P2.X = 2;
__r.P2.Y = 3;
Rectangle r = __r;
来源:https://stackoverflow.com/questions/32897655/new-c-sharp-6-object-initializer-syntax