使用对象初始化语法的操作顺序

发布于 2024-07-13 03:35:01 字数 254 浏览 10 评论 0原文

我使用对象初始值设定项语法设置属性的顺序是否以完全相同的顺序执行?

例如,如果我这样做:

var s = new Person { FirstName = "Micah",
                     LastName = "Martin",
                     IsLoaded = true
                   }

每个属性都会以相同的顺序设置吗?

Does the order in which I set properties using the object initializer syntax get executed in the exact same order?

For instance if I do this:

var s = new Person { FirstName = "Micah",
                     LastName = "Martin",
                     IsLoaded = true
                   }

will each property get set in the same order?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜点 2024-07-20 03:35:01

是的。

很抱歉被打扰(我实际上必须经常做一些工作)。 规范没有明确说明这一点,但在第 7.6.10.2 节中,它在 IMO 中说得很清楚:


对象初始值设定项由一系列成员初始值设定项组成,由 { 和 } 标记括起来并用逗号分隔。

(请注意这里的“序列”一词,而不是“集合”。我个人认为这很重要,因为序列是有序的。)

以下类表示具有两个坐标的点:

public class Point
{
    int x, y;
    public int X { get { return x; } set { x = value; } }
    public int Y { get { return y; } set { y = value; } }
}

Point 的实例可以如下创建和初始化:

Point a = new Point { X = 0, Y = 1 };

其效果与

Point __a = new Point();
__a.X = 0;
__a.Y = 1; 
Point a = __a;

__a 是不可见且无法访问的临时变量的情况相同。


编辑:我收到了 Mads Torgersen 的回复,他基本上说现在可以做的任何事情都将维持秩序。 将来可能会出现一些奇怪的情况,在奇怪的情况下,您正在执行除设置属性/字段之外的其他操作,但顺序不会保留,但这取决于语言的位置。

值得指出的是,这里实际上有很多步骤 - 有参数评估的执行顺序(即 RHS 位)和赋值的执行顺序。 例如,如果:

new Foo
{
    A = X,
    B = Y
}

以下所有顺序都是可能的,同时仍保持实际属性执行的顺序(A 和 B):

  • 评估 X,分配给 A,评估 Y,分配给 B
  • 评估 X,评估 Y,分配给A,分配给 B
  • 评估 Y,评估 X,分配给 A,分配给 B

我相信第一个选项是实际采用的选项,但这只是为了证明它的内容比表面上看到的要多。

我也会非常对实际编写依赖于此的代码保持警惕......

Yes.

Apologies for getting interrupted (I have to actually do some work every so often). The spec doesn't explicitly say it, but it makes it pretty clear IMO in section 7.6.10.2:


An object initializer consists of a sequence of member initializers, enclosed by { and } tokens and separated by commas.

(Note the word "sequence" here, rather than "set". I personally think that's significant, as a sequence is ordered.)

The following class represents a point with two coordinates:

public class Point
{
    int x, y;
    public int X { get { return x; } set { x = value; } }
    public int Y { get { return y; } set { y = value; } }
}

An instance of Point can be created and initialized as follows:

Point a = new Point { X = 0, Y = 1 };

which has the same effect as

Point __a = new Point();
__a.X = 0;
__a.Y = 1; 
Point a = __a;

where __a is an otherwise invisible and inaccessible temporary variable.


EDIT: I've had a response from Mads Torgersen, who has basically said that anything which can be done now will preserve the order. There may be some oddities in future where the order is not preserved in weird cases where you're doing something other than setting a property/field, but that will depend on where the language goes.

It's worth pointing out that there are actually lots of steps going on here - there's the order of execution of the evaluation of the arguments (i.e. the RHS bits) and the order of execution of the assignments. For example, if you have:

new Foo
{
    A = X,
    B = Y
}

all the following orders are possible while still maintaining the order of the actual property execution (A and B):

  • Evaluate X, assign to A, evaluate Y, assign to B
  • Evaluate X, evaluate Y, assign to A, assign to B
  • Evaluate Y, evaluate X, assign to A, assign to B

I believe the first option is the one actually taken, but this was just to demonstrate that there's more to it than meets the eye.

I would also be very wary of actually writing code which depends on this...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文