繁体   English   中英

从左到右的表达评估

[英]Left to right expression evaluation

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

例如:

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

有没有不符合的语言?

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

这意味着:当逻辑表达式的结果不再发生变化时,例如,当表达式无论如何都将评估为“真”或“假”时,表达式的剩余部分将不会被评估。

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

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

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

如果MyClass为null:

  • MyClass == null计算结果为true
  • 因为它是一个“或”表达式,所以后面的内容并不重要
  • 不再进行评估,最终结果是真的

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

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

操作x || y对应于操作x | y,除了仅在x不为真时才计算y。

是的,你很好。

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

不过要小心:

如果你有类似的东西

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

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

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

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

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

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

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

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

Python有短路or and运营商。

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

有趣的是:在Haskell中,这自然与语言(您可以定义自己的运算符来实现),而在Java和C#中,它是特定于这两个运算符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM