我通过以这种方式初始化字段来创建对象:
class Example
{
public int a;
public int b;
}
var obj = new Example
{
a = stream.ReadInt(),
b = stream.ReadInt()
};
是否始终在字段“b”之前初始化字段“a”?否则,当以不同的顺序减去流中的值时,可能会发生令人不快的错误。谢谢!
UPD:在评论中,很多人都不理解我的意思。 我会澄清这个问题。这些记录在不同的(.NET,Mono等)编译器上的行为是否始终相同?首先:
var obj = new Example
{
a = stream.ReadInt(),
b = stream.ReadInt()
};
第二
var a = stream.ReadInt();
var b = stream.ReadInt();
var obj = new Example
{
a = a,
b = b
};
答案 0 :(得分:3)
对象初始值设定项由序列的成员初始值设定项
组成
[强调我的]。单词" sequence"必然意味着一个订单。也许这似乎并不具有规范性,但他们的例子确实如此:
可以按如下方式创建和初始化Point的实例:
Point a = new Point { X = 0, Y = 1 };
与
具有相同的效果Point __a = new Point(); __a.X = 0; __a.Y = 1; Point a = __a;
如果编译器作者要对分配重新排序,则他们输出的程序将不符合上述示例。
更一般地说,在该部分中查看语言的其余部分是非常有用的,因为语言设计者竭尽全力确保该功能直观地工作,包括对象初始化器的嵌套分配仅指定父属性的完全形成的对象。
所有这一切,真的不应该。如果你有一个课程,其中两个或多个属性的作业顺序影响最终结果,那么你手上就有一个非常危险的课程。应该不惜一切代价避免这样的设计,因为在任何情况下都很容易破解,即使对象初始化的编译器规则相当清楚。
答案 1 :(得分:0)
这种结构被称为"对象初始化器"不应与object / field 初始化混淆。在完全构造之后修改对象是一种很好的语法。
根据C#5.0规范的 7.6.10.2 - Object Initializers 中的示例:
可以按如下方式创建和初始化Point的实例:
Point a = new Point { X = 0, Y = 1 };
与
具有相同的效果Point __a = new Point(); __a.X = 0; __a.Y = 1; Point a = __a;
规范示例隐含地涵盖赋值的排序(这意味着以特定顺序评估RHS)以及分配的总顺序。创建对象(即,在处理对象初始值设定项之前,不会将对象分配给字段)。