从左到右的表达评估

时间:2008-12-03 10:29:21

标签: c# language-agnostic compiler-construction expression expression-evaluation

在C#中,是否保证表达式从左到右进行评估?

例如:

myClass = GetClass();  
if (myClass == null || myClass.Property > 0)  
    continue;

是否有任何语言不符合要求?

9 个答案:

答案 0 :(得分:14)

您实际上是指一种名为“短路逻辑表达式”的语言功能:

这意味着什么:当逻辑表达式的结果不再改变时,例如当很明显表达式将评估为“真”或“假”时,无论如何,表达式的其余部分将不会被评估。

例如,C#,Java或JavaScript就是这样做的,你可以用这些语言来依赖它(回答你的问题)。

在您的情况下,如果MyClass不为null:

  • MyClass == null评估为false
  • 因为它是一个“或”表达式,第二部分仍然可以改变结果,所以它被评估
  • myClass.Property > 0确定最终结果

如果MyClass为null:

  • MyClass == null评估为真
  • 因为它是“或”表达式,所以后面的内容无关紧要
  • 不再进行评估,最终结果为真

有些语言不会使逻辑表达式短路。经典VB就是一个例子,如果MyClass为null(在VB中称为“Nothing”),将评估“myClass.Property> 0”并产生错误。

答案 1 :(得分:5)

C#3.0规范的第7.11节描述了短路:

  

操作x || y对应于   操作x | y,除了y是   仅在x不为真的情况下进行评估。

是的,你没事。

至于其他语言 - 我从不喜欢说所有语言。在VB.NET中,你可以使用OrElse和AndAlso,它们是短路的,但是普通的Or和And不是。

答案 2 :(得分:2)

但要小心:

如果您有类似

的内容

sprintf(buf,“%s%s”,func1(& var),func2(& var));

对var的sideeffects,它没有定义(在C中,我不确定评估顺序是否在其他语言中定义),执行func1()和func2()的顺序(它取决于,顺序是什么(左或右)参数放在堆栈上并从那里进行评估。

答案 3 :(得分:0)

评估顺序取决于运算符,在这种情况下,布尔值或(||)被定义为通常称为short-circuiting的,以使这样的结构起作用。

答案 4 :(得分:0)

我不确定,您对订单或短路评估真的感兴趣吗?

我不是百分百肯定,但据我所知,评估的顺序在C#中总是相同的(我假设大多数(如果不是全部.net语言))。短路评估的工作方式如前面的答案中所述。

但是,在C#中,您可以选择不使用简单的运算符(&而不是&&)进行短路。通常您想要短路,但可能是您想要执行所有评估的情况。

答案 5 :(得分:0)

Ada,Visual Basic和Pascal等语言中的和/或运算符不会短路。它们确实提供了额外的操作符来允许该功能,例如Ada中的“然后”和“或者”。

答案 6 :(得分:0)

Python有短路orand运算符。

答案 7 :(得分:0)

在Java和Haskell&&和||短路也是如此。

有趣的是:在Haskell中,这很自然地与语言(您可以定义自己的运算符)相同,而在Java和C#中,这两个运算符是特定的

答案 8 :(得分:0)

实际上,短路是其中的一部分,但您还需要知道该语言是否保证了这些语言的从左到右的评估。例如,C(ANSI,ISO,C99)不保证从左到右的评估。在示例代码中,可以在检查NULL之前检查Property的值,或者同时执行两者...大多数编译器都没有,但是没有什么能阻止它执行此操作并完全符合规范。它甚至告诉你不要写这样的代码。