C# 逻辑顺序和编译器行为

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-07-31 16:24:01  来源:igfitidea点击:

C# logic order and compiler behavior

提问by Seibar

In C#, (and feel free to answer for other languages), what order does the runtime evaluate a logic statement?

在 C# 中(并且可以随意回答其他语言),运行时评估逻辑语句的顺序是什么?

Example:

例子:

DataTable myDt = new DataTable();
if (myDt != null && myDt.Rows.Count > 0)
{
    //do some stuff with myDt
}

Which statement does the runtime evaluate first -

运行时首先评估哪个语句 -

myDt != null

or:

或者:

myDt.Rows.Count > 0

?

?

Is there a time when the compiler would ever evaluate the statement backwards? Perhaps when an "OR" operator is involved?

编译器是否会向后评估语句?也许当涉及“OR”运算符时?



& is known as a logical bitwise operator and will always evaluate all the sub-expressions

& 被称为逻辑按位运算符,将始终评估所有子表达式

What is a good example of when to use the bitwise operator instead of the "short-circuited boolean"?

什么时候使用按位运算符而不是“短路布尔值”的好例子是什么?

采纳答案by ZombieSheep

C# : Left to right, and processing stops if a non-match (evaluates to false) is found.

C#:从左到右,如果发现不匹配(计算结果为 false),则处理停止。

回答by Shawn

The left one, then stops if it is null.

左边的一个,如果它为空则停止。

Edit: In vb.net it will evaluate both and possibly throw an error, unless you use AndAlso

编辑:在 vb.net 中,它将评估两者并可能引发错误,除非您使用 AndAlso

回答by GateKiller

I have heard somewhere that compilers work backwards, but I am unsure how true this is.

我在某处听说编译器向后工作,但我不确定这是多么真实。

回答by csmba

vb.net

网络

if( x isNot Nothing AndAlso x.go()) then
  1. Evaluation is done left to right
  2. AndAlsooperator makes sure that only if the left side was TRUE, the right side will be evaluated (very important, since ifx is nothing x.go will crash)
  1. 评估是从左到右进行的
  2. AndAlso运算符确保仅当左侧为 TRUE 时,才会评估右侧(非常重要,因为 ifx is nothing x.go 会崩溃)

You may use Andinstead ofAndAlso in vb. in which case the left side gets evaluated first as well, but the right side will get evaluated regardless of result.

你可以在 vb 中使用And而不是 AndAlso。在这种情况下,左侧也会首先被评估,但无论结果如何,右侧都会被评估。

Best Practice: Always use AndAlso, unless you have a very good reason why not to.

最佳实践:始终使用 AndAlso,除非您有充分的理由不这样做。



It was asked in a followup why or when would anyone use And instead of AndAlso (or & instead of &&):Here is an example:

后续有人问为什么或何时有人会使用 And 而不是 AndAlso(或 & 而不是 &&):这是一个例子:

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

In this case, I want to init both X and Y. Y must be initialized in order for y.DoDance to be able to execute. However, in the init() function I am doing also some extra thing like checking a socket is open, and only if that works out ok, for both, I should go ahead and do the x.process(y).

在这种情况下,我想同时初始化 X 和 Y。Y 必须被初始化,以便 y.DoDance 能够执行。但是,在 init() 函数中,我还做了一些额外的事情,例如检查套接字是否打开,并且只有当这一切正常时,对于两者,我才应该继续执行 x.process(y)。

Again, this is probably not needed and not elegant in 99% of the cases, that is why I said that the default should be to use AndAlso.

同样,在 99% 的情况下这可能不是必需的并且不优雅,这就是为什么我说默认应该使用AndAlso

回答by shsteimer

The concept modesty is referring to is operator overloading. in the statement:

谦虚所指的概念是运算符重载。在声明中:

if( A && B){
    // do something
}

A is evaluated first, if it evaluates to false, B is never evaluated. The same applies to

A 首先被评估,如果它评估为假,则永远不会评估 B。这同样适用于

if(A || B){
    //do something
}

A is evaluated first, if it evaluates to true, B is never evaluated.

A 首先被评估,如果它的评估结果为真,则永远不会评估 B。

This concept, overloading, applies to (i think) all of the C style languages, and many others as well.

这个概念,重载,适用于(我认为)所有的 C 风格语言,以及许多其他语言。

回答by Brad Tutterow

ZombieSheep is dead-on. The only "gotcha" that might be waiting is that this is only true if you are using the && operator. When using the & operator, both expressions will be evaluated every time, regardless if one or both evaluate to false.

ZombieSheep 已经死了。唯一可能需要等待的“问题”是,这仅在您使用 && 运算符时才成立。使用 & 运算符时,每次都会对这两个表达式进行评估,无论其中一个或两个表达式的计算结果为 false。

if (amHungry & whiteCastleIsNearby)
{
   // The code will check if White Castle is nearby
   // even when I am not hungry
}

if (amHungry && whiteCastleIsNearby)
{
   // The code will only check if White Castle is nearby
   // when I am hungry
}

回答by Lasse V. Karlsen

Note that there is a difference between && and & regarding how much of your expression is evaluated.

请注意,&& 和 & 之间存在差异关于评估多少表达式。

&& is known as a short-circuited boolean AND, and will, as noted by others here, stop early if the result can be determined before all the sub-expressions are evaluated.

&& 被称为短路布尔AND,并且正如其他人所指出的那样,如果可以在评估所有子表达式之前确定结果,则将提前停止。

& is known as a logical bitwise operator and will always evaluate all the sub-expressions.

& 被称为逻辑按位运算符,将始终评估所有子表达式。

As such:

像这样:

if (a() && b())

Will only call bif areturns true.

只有在a返回true 时才会调用b

however, this:

然而,这:

if (a() & b())

Will always call both aand b, even though the result of calling ais false and thus known to be falseregardless of the result of calling b.

将始终同时调用ab,即使调用a的结果是假的,因此无论调用b的结果如何都知道是的。

This same difference exists for the || and | operators.

|| 也存在同样的差异 和| 运营商。

回答by Mike Stone

Some languages have interesting situations where expressions are executed in a different order. I am specifically thinking of Ruby, but I'm sure they borrowed it from elsewhere (probably Perl).

有些语言有一些有趣的情况,其中表达式以不同的顺序执行。我特别想到 Ruby,但我确信他们是从其他地方(可能是 Perl)借来的。

The expressions in the logic will stay left to right, but for example:

逻辑中的表达式将保持从左到右,但例如:

puts message unless message.nil?

The above will evaluate "message.nil?" first, then if it evaluates to false (unless is like if except it executes when the condition is false instead of true), "puts message" will execute, which prints the contents of the message variable to the screen.

以上将评估“message.nil?” 首先,然后如果它的计算结果为假(除非就像 if except 它在条件为假而不是真时执行),“puts message”将执行,它将消息变量的内容打印到屏幕上。

It's kind of an interesting way to structure your code sometimes... I personally like to use it for very short 1 liners like the above.

有时,这是一种构建代码的有趣方式……我个人喜欢将它用于非常短的 1 行,如上述。

Edit:

编辑:

To make it a little clearer, the above is the same as:

为了更清楚一点,上面的内容与以下内容相同:

unless message.nil?
  puts message
end

回答by Vaibhav

Nopes, at least the C# compiler doesn't work backwards (in either && or ||). It's left to right.

不,至少 C# 编译器不会向后工作(在 && 或 || 中)。从左到右。

回答by Bruce Alderman

What is a good example of when to use the bitwise operator instead of the "short-circuited boolean"?

什么时候使用按位运算符而不是“短路布尔值”的好例子是什么?

Suppose you have flags, say for file attributes. Suppose you've defined READ as 4, WRITE as 2, and EXEC as 1. In binary, that's:

假设您有标志,例如文件属性。假设您已将 READ 定义为 4,将 WRITE 定义为 2,并将 EXEC 定义为 1。在二进制中,即:

READ  0100  
WRITE 0010  
EXEC  0001

Each flag has one bit set, and each one is unique. The bitwise operators let you combine these flags:

每个标志都设置了一位,并且每一位都是唯一的。按位运算符可让您组合这些标志:

flags = READ & EXEC; // value of flags is 0101