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

Does C# guarantee evaluation order of branched nested expressions?

C# 显然可以处理嵌套和链式表达式。 如果嵌套 and/or 链接是线性的,那么很明显表达式的计算顺序是:

Foo(Bar(Baz().Bop()))只能按以下顺序求值:

但是如果嵌套不是线性的呢?考虑:Foo(Baz()).Bar(Bop())

显然以下必须全部为真:

但尚不清楚 Bop 的确切评估时间。 以下任何一项都是可行的订单:

我的直觉是第三个选项可能是正确的。也就是说,它将在开始评估 .Bar(Bop())

any 之前完全评估 Foo(Baz())

虽然我当然可以测试个别情况以查看会发生什么,但这并不能告诉我我的猜测是否总是是真的?

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

如果不是,是否至少知道它是确定性的?

您会在 Section 11 of the specification 中找到答案。

具体来说,11.6.6 Function member invocation 表示:

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.

因此,给定表达式 E.M(A)EA 被求值之前被完全求值。

对于 Foo(Baz()).Bar(Bop()) 的情况,如果我们查看 Bar 的评估(所以 EFoo(Baz())MBar 并且参数列表是 Bop()),这意味着 Foo (E) 必须在 Bop(参数列表)被评估之前被完全评估,这意味着“可能性 #3”是正确的。

还有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

所以在表达式 M(A, B) 中,AB 被求值之前被完全求值。