简体   繁体   English

从左到右的表达评估

[英]Left to right expression evaluation

In C# is it guaranteed that expressions are evaluated left to right? 在C#中,是否保证表达式从左到右进行求值?

For example: 例如:

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

Are there any languages that do not comply? 有没有不符合的语言?

You actually refer to a language feature called "short-circuiting logical expressions": 您实际上是指一种称为“短路逻辑表达式”的语言功能:

What this means is this: When the outcome of a logical expression cannot change anymore, eg when it is clear that the expression will evaluate to "true" or "false" no matter what, remaining parts of the expression will not be evaluated. 这意味着:当逻辑表达式的结果不再发生变化时,例如,当表达式无论如何都将评估为“真”或“假”时,表达式的剩余部分将不会被评估。

For example, C#, Java or JavaScript do that, and you can rely on it in those languages (to answer your question). 例如,C#,Java或JavaScript就是这样做的,你可以用这些语言来依赖它(回答你的问题)。

In your case, if MyClass is not null: 在您的情况下,如果MyClass不为null:

  • MyClass == null evaluates to false MyClass == null计算结果为false
  • since it is an "or" expression, the second part still can change the result, so it is evaluated 因为它是一个“或”表达式,第二部分仍然可以改变结果,所以它被评估
  • myClass.Property > 0 determines the end result myClass.Property > 0确定最终结果

if MyClass is null: 如果MyClass为null:

  • MyClass == null evaluates to true MyClass == null计算结果为true
  • since it is an "or" expression, it does not matter what follows 因为它是一个“或”表达式,所以后面的内容并不重要
  • no more evaluation is done, the end result is true 不再进行评估,最终结果是真的

There are languages that do not short-circuit logical expressions. 有些语言不会使逻辑表达式短路。 Classical VB is an example, here "myClass.Property > 0" would be evaluated and produce an error if MyClass was null (called "Nothing" in VB). 经典VB就是一个例子,如果MyClass为null(在VB中称为“Nothing”),将评估“myClass.Property> 0”,并产生错误。

Short-circuiting is described in section 7.11 of the C# 3.0 spec: C#3.0规范的第7.11节描述了短路:

The operation x || 操作x || y corresponds to the operation x | y对应于操作x | y, except that y is evaluated only if x is not true. y,除了仅在x不为真时才计算y。

So yes, you're fine. 是的,你很好。

As for other languages - I never like to speak for all languages. 至于其他语言 - 我从不喜欢说所有语言。 In VB.NET, you can use OrElse and AndAlso which are short-circuited, but plain Or and And aren't. 在VB.NET中,你可以使用OrElse和AndAlso,它们是短路的,但是普通的Or和And不是。

But be careful: 不过要小心:

if you have something like 如果你有类似的东西

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

with sideeffects on var, it is not defined (in C, i am not sure if the evaluation order is defined in other languages), in which order func1() and func2() are executed (it depends, in what order (left or right) the arguments are put on the stack and evaluated from there. 对于var的sideeffects,它没有定义(在C中,我不确定评估顺序是否在其他语言中定义),执行func1()和func2()的顺序(它取决于,以什么顺序(左或右)将参数放在堆栈上并从那里进行评估。

Actually short-circuiting is part, but you also need to know whether the language guarantees left-to-right evaluation of those. 实际上,短路是其中的一部分,但您还需要知道该语言是否能保证对这些语言进行从左到右的评估。 For instance C (ANSI, ISO, C99) do NOT guarantee left-to-right evaluation. 例如,C(ANSI,ISO,C99)不保证从左到右的评估。 In the sample code it would be possible to check the value of Property before checking for NULL or do both simultaneously... most compilers don't, but there's nothing preventing it from doing that and being fully compliant with the spec. 在示例代码中,可以在检查NULL之前检查Property的值,或者同时执行两者...大多数编译器都没有,但是没有什么能阻止它执行此操作并完全符合规范。 It even tells you NOT to write such code because of this. 它甚至告诉你不要因为这个而编写这样的代码。

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

I'm not sure, are you really interested in order or in short-circuit evaluation? 我不确定,您对订单或短路评估真的感兴趣吗?

I'm not 100% sure, but as far as I know the order of evaluation will always be the same in C# (and I assume most if not all of .net languages). 我不是百分百肯定,但据我所知,评估的顺序在C#中总是相同的(我假设大多数(如果不是全部.net语言))。 Short-circuit evaluation works as explained in the previous answers. 短路评估的工作原理如前面的答案所述。

However, in C# you can choose not to short circuit using simple operators (& instead of &&). 但是,在C#中,您可以选择不使用简单的运算符(而不是&&)进行短路。 Normally you want to short-circuit, but it may be a case in which you want to execute all the evaluations. 通常您想要短路,但可能是您想要执行所有评估的情况。

The and/or operators in languages like Ada, Visual Basic, and Pascal do not short-circuit. Ada,Visual Basic和Pascal等语言中的和/或运算符不会短路。 They do provide extra operators to allow that functionality, such as "and then" and "or else" in Ada. 它们确实提供了额外的操作符来允许该功能,例如Ada中的“然后”和“或者”。

Python有短路or and运营商。

In Java and Haskell && and || 在Java和Haskell &&和||中 short-circuit as well. 短路也是如此。

Interesting aside: in Haskell this comes naturally with the language (you can define your own operators that do this), while in Java and C# it is specific for those two operators. 有趣的是:在Haskell中,这自然与语言(您可以定义自己的运算符来实现),而在Java和C#中,它是特定于这两个运算符。

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

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