c# - 使用嵌套对象时对象初始化程序中的赋值顺序

标签 c# object-initializers

我有以下代码使用对象初始化程序创建 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

我问的原因是,为给定的Root修改Person的getter和setter非常复杂,我想避免调用它的getter为了设置该Person的属性。

最佳答案

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.P1Rectangle.P2 属性是从已创建的 Point 对象初始化的。

这证明了你问题的答案

Is Person completely created and than assigned to the new instance of Root?

肯定是:是的。

关于c# - 使用嵌套对象时对象初始化程序中的赋值顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41893221/

相关文章:

c# - 如何隐藏折线图中数据点的标签

c# - 集合类型的初始容量,例如字典、列表

C# 嵌套对象初始值设定项

c# - 如何判断对象初始化程序何时完成

c++ - 包装类的静态初始化列表

c# - 发生引用完整性约束冲突

c# - 向 Web API Controller 发出请求后 session 变量被重置

c# - 在 C# 中的 json 文件中追加数据

C# 相当于 Scala List 的带索引的 Zip?

c# - 在对象初始值设定项中使用 "this"