C# 从左到右表达式求值
在C#中,是否保证表达式从左到右求值 例如:C# 从左到右表达式求值,c#,language-agnostic,compiler-construction,expression,expression-evaluation,C#,Language Agnostic,Compiler Construction,Expression,Expression Evaluation,在C#中,是否保证表达式从左到右求值 例如: myClass = GetClass(); if (myClass == null || myClass.Property > 0) continue; 有没有不符合要求的语言?计算顺序取决于运算符,在这种情况下,布尔or()被定义为通常所称的,以使类似的构造工作。您实际上指的是一种称为“短路逻辑表达式”的语言功能: 这意味着:当逻辑表达式的结果不能再更改时,例如,无论发生什么情况,表达式的计算结果都明显为“真”或“假”,则表
myClass = GetClass();
if (myClass == null || myClass.Property > 0)
continue;
有没有不符合要求的语言?计算顺序取决于运算符,在这种情况下,布尔or(
)被定义为通常所称的,以使类似的构造工作。您实际上指的是一种称为“短路逻辑表达式”的语言功能:
这意味着:当逻辑表达式的结果不能再更改时,例如,无论发生什么情况,表达式的计算结果都明显为“真”或“假”,则表达式的其余部分将不进行计算
例如,C#、Java或JavaScript可以做到这一点,在这些语言中,您可以依赖它(来回答您的问题)
在您的情况下,如果MyClass不为null:
计算结果为falseMyClass==null
- 由于它是一个“或”表达式,第二部分仍然可以更改结果,因此将对其进行计算
确定最终结果myClass.Property>0
计算结果为trueMyClass==null
- 因为它是一个“或”表达式,所以后面的内容并不重要
- 不再进行评估,最终结果是真实的
有些语言不会使逻辑表达式短路。经典VB就是一个例子,这里“myClass.Property>0”将被计算,如果myClass为null(在VB中称为“Nothing”)将产生错误。短路在C#3.0规范的第7.11节中描述: 操作x | | y对应于 操作x | y,除了y是 仅当x不为真时才计算 是的,你很好 至于其他语言,我从来不喜欢说所有的语言。在VB.NET中,您可以使用OrElse和AndAlso,它们是短路的,但不是普通的。但要小心: 如果你有 sprintf(buf,“%s%s”、func1(&var)、func2(&var))
对于var的sideeffects,它没有定义(在C中,我不确定是否用其他语言定义了求值顺序),以什么顺序执行func1()和func2()(这取决于,以什么顺序(左或右)参数被放在堆栈上并从那里进行计算。我不确定,您真的对顺序或短路计算感兴趣吗 我不是100%确定,但据我所知,C#中的评估顺序始终是相同的(我假设大多数,如果不是所有的.net语言的话)。短路评估的工作原理如前面的答案所述
但是,在C#中,您可以选择不使用简单运算符短路(&而不是&&)。通常情况下,您希望短路,但在这种情况下,您可能希望执行所有计算。Ada、Visual Basic和Pascal等语言中的and/or运算符不会短路。它们提供了额外的运算符以允许该功能,例如“and then”和“or else”在Ada中。Python有短路
或和和运算符。在Java和Haskell中也有短路
有趣的旁白:在Haskell语言中,这是很自然的(您可以定义自己的运算符来实现这一点),而在Java和C中,这是这两个运算符特有的。实际上短路是其中的一部分,但您还需要知道该语言是否保证对这些运算符进行从左到右的计算。例如C(ANSI、ISO、C99)不要保证从左到右求值。在示例代码中,可以在检查NULL之前检查属性值,或者同时执行这两项操作……大多数编译器不这样做,但没有任何东西可以阻止它这样做并完全符合规范。它甚至会告诉您不要为此编写此类代码。在C中#定义了精确的顺序。