问题
In C# is it guaranteed that expressions are evaluated left to right?
For example:
myClass = GetClass();
if (myClass == null || myClass.Property > 0)
continue;
Are there any languages that do not comply?
回答1:
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, e.g. 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).
In your case, if MyClass is not null:
MyClass == null
evaluates to 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
if MyClass is null:
MyClass == null
evaluates to 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).
回答2:
Short-circuiting is described in section 7.11 of the C# 3.0 spec:
The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is not true.
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.
回答3:
But be careful:
if you have something like
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.
回答4:
The evaluation order depends on the operator, in this case the boolean or (||
) is defined to be what is commonly called short-circuiting, to make constructs like this work.
回答5:
The and/or operators in languages like Ada, Visual Basic, and Pascal do not short-circuit. They do provide extra operators to allow that functionality, such as "and then" and "or else" in Ada.
回答6:
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). 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 &&). Normally you want to short-circuit, but it may be a case in which you want to execute all the evaluations.
回答7:
Python has short-circuit or
and and
operators.
回答8:
In Java and Haskell && and || 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.
回答9:
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. 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. It even tells you NOT to write such code because of this.
来源:https://stackoverflow.com/questions/336755/left-to-right-expression-evaluation