我有以下代码使用object-initializer创建Root
的实例:
var r = new Root { Person = new Person { Age = 20, Name = "Hans" } };
来自Is there any benefit of using an Object Initializer?我知道如果我们只有内部对象Person
,则会将其翻译为以下内容:
var p = new Person();
p.Age = 20;
p.Name = 20;
我想知道这是如何影响我的第一个例子中的嵌套对象的? Person
是否已完全创建并分配给Root
的新实例,或者仅仅转换为以下内容:
var r = new Root();
r.Person = new Person();
r.Person.Age = 20; // this would call the Persons getter
r.Person.Name = "Hans"; // this would call the Persons getter
我问的原因是为给定Person
修改Root
的getter和setter非常复杂,我想避免为了设置属性而调用其getter对于Person
。
答案 0 :(得分:2)
这在C#语言规范的7.6.10.2中明确提到。
该标准为“嵌套对象初始化器”提供了此示例:
public class Point
{
int x, y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
public class Rectangle
{
Point p1, p2;
public Point P1 { get { return p1; } set { p1 = value; } }
public Point P2 { get { return p2; } set { p2 = value; } }
}
Rectangle r = new Rectangle
{
P1 = new Point { X = 0, Y = 1 },
P2 = new Point { X = 2, Y = 3 }
};
标准说这与下面的效果相同:
Rectangle __r = new Rectangle();
Point __p1 = new Point();
__p1.X = 0;
__p1.Y = 1;
__r.P1 = __p1;
Point __p2 = new Point();
__p2.X = 2;
__p2.Y = 3;
__r.P2 = __p2;
Rectangle r = __r;
您可以在此处看到Rectangle.P1
和Rectangle.P2
属性是从已创建的Point
对象初始化的。
这证明了你问题的答案
是否完全创建了Person并将其分配给Root的新实例?
明确地说:是的。
答案 1 :(得分:1)
我们可以通过在Person
- 类中的Root
的getter中设置断点来轻松检查这一点。调试时我们注意到它从未被击中。
这确实导致创建了以下对象图:
var p = new Person();
p.Age = 20;
p.Name = "Hans";
var r = new Root();
r.Person = p;
您看到没有访问任何getter来设置人员属性,因为Person
是先创建 ,而Root
甚至存在之前。
这可确保仅在先前已完全创建Root
时才完全创建Person
。