C#是否保证分支嵌套表达式的评估顺序?

发布于 2025-01-23 06:50:31 字数 1282 浏览 0 评论 0 原文

C#显然可以处理嵌套和链式表达式。 如果嵌套和/或链式是线性的,则很明显在以下方式中评估表达式的顺序:

foo(baz(baz()。bop())) can can 唯一的评估评估按照以下顺序:

  • baz()
  • bop()
  • bar()
  • foo()

但是如果嵌套不是线性吗?考虑: foo(baz())。bar(bop(bop())

显然必须是正确的:

  • baz foo
  • foo bar
  • bop bar

之前,但尚不清楚何时 bop 进行评估。 以下任何一个都是可行的顺序:

  • 可能性#1
    • bop()
    • baz()
    • foo()
    • bar()
  • 可能性#2
    • baz()
    • bop()
    • foo()
    • bar()
  • 可能性#3
    • baz()
    • foo()
    • bop()
    • bar()

我的本能是3rd Option可能是正确的。即,在开始评估 .bar(bop())之前,它将完全评估 foo(baz())

当然,测试个人情况以查看发生的情况,这不会告诉我我的猜测是否会始终是真的吗?

但是我的问题是: 是定义为C#语言规范一部分的分支嵌套表达式的评估顺序,还是留给编译器的情境判断

C# handles both nested and chained expressions, obviously.
If the nesting and/or chaining is linear then it's evident what order the expressions are evaluated in:

Foo(Bar(Baz().Bop())) can only evaluate in the following order:

  • Baz()
  • Bop()
  • Bar()
  • Foo()

But what if the nesting isn't linear? Consider: Foo(Baz()).Bar(Bop())

Clearly the following MUST all be true:

  • Baz before Foo
  • Foo before Bar
  • Bop before Bar

But it's not clear exactly when Bop will be evaluated.
Any of the following would be a viable order:

  • Possibility #1
    • Bop()
    • Baz()
    • Foo()
    • Bar()
  • Possibility #2
    • Baz()
    • Bop()
    • Foo()
    • Bar()
  • Possibility #3
    • Baz()
    • Foo()
    • Bop()
    • Bar()

My instinct is that the 3rd option is likely correct. i.e. that it will fully evaluate Foo(Baz()) before it starts to evaluate any of .Bar(Bop())

Whilst I could certainly test an individual situation to see what happens, that doesn't tell me whether my guess will always be true?

But my question is:
Is the order of evaluation of branched nested expressions defined as part of the C# language specification, or left to the situational judgement of the compiler?

If not, is it at least known to be deterministic?

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

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

发布评论

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

评论(1

深居我梦 2025-01-30 06:50:32

您会在

具体来说,说:

函数成员调用的运行时处理由以下步骤组成,其中 m 是函数成员,如果 m 是实例成员, e 是实例表达式:
...

  • e 已评估。如果此评估导致例外,则不会执行进一步的步骤。
  • 参数列表的评估如第11.6.2节所述。

因此,在评估 a 之前,给定表达式 em(a) e

对于 foo(baz())。bar(bop())案例,如果我们正在查看 bar 的评估(因此 e is foo(baz()) m is bar ,参数列表为 bop()),这意味着在评估 e )之前,必须在评估 bop (参数列表)之前对其进行全面评估,这意味着“可能性#3”是正确的。

还有 11.6.2.3参数列表的运行时间评估

在函数成员调用(第11.6.6节)的运行时处理过程中,请从左到右评估参数列表的表达式或变量引用

因此在expression m(a,b)< /code>, a 在评估 b 之前进行了充分评估。

You'll find the answers in Section 11 of the specification.

Specifically, 11.6.6 Function member invocation says:

The run-time processing of a function member invocation consists of the following steps, where M is the function member and, if M is an instance member, E is the instance expression:
...

  • E is evaluated. If this evaluation causes an exception, then no further steps are executed.
  • The argument list is evaluated as described in §11.6.2.

So, given an expression E.M(A), E is fully evaluated before A is evaluated.

For the Foo(Baz()).Bar(Bop()) case, if we're looking at the evaluation of Bar (so E is Foo(Baz()), M is Bar and the argument list is Bop()), this means that Foo (E) must have been fully evaluated before Bop (the argument list) is evaluated, meaning that "possibility #3" is the correct one.

There's also 11.6.2.3 Run-time evaluation of argument lists:

During the run-time processing of a function member invocation (§11.6.6), the expressions or variable references of an argument list are evaluated in order, from left to right

So in the expression M(A, B), A is fully evaluated before B is evaluated.

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