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

例:

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

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

myDt != null

要么:

myDt.Rows.Count > 0

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


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

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

===============>>#1 票数:16 已采纳

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

===============>>#2 票数:9

“C#:从左到右,如果找到匹配(评估为真),则处理停止。”

僵尸羊是错的,没有足够的代表下来投票。

问题是关于&&运算符,而不是|| 运营商。

在&&的情况下,如果找到FALSE,则评估将停止。

在||的情况下 如果找到TRUE,评估将停止。

===============>>#3 票数:8

我意识到这个问题已经得到了回答,但是我想提出与该主题相关的另一些信息。

在像C ++这样的语言中,你实际上可以重载&&和||的行为 运营商,强烈建议您不要这样做 这是因为当您重载此行为时,最终会强制对操作的两端进行评估。 这有两件事:

  1. 它打破了惰性求值机制,因为重载是一个必须调用的函数,因此在调用函数之前会对这两个参数进行求值。
  2. 不保证所述参数的评估顺序,并且可以是编译器特定的。 因此,对象的行为方式与问题/先前答案中列出的示例中的行为方式不同。

有关更多信息,请阅读Scott Meyers的书“ 更有效的C ++” 干杯!

===============>>#4 票数:6

vb.net

if( x isNot Nothing AndAlso x.go()) then
  1. 评估从左到右进行
  2. AndAlso运算符确保只有左侧为TRUE,才会评估右侧(非常重要,因为ifx不是x.go会崩溃)

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

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


在后续跟踪中询问为什么或何时使用And而不是AndAlso(或&而不是&&):这是一个例子:

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

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

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

===============>>#5 票数:5

@shsteimer

概念模式指的是运算符重载。 在语句中:...首先评估A,如果评估为false,则从不评估B. 这同样适用于

那不是运营商超载。 运算符重载是允许您为运算符定义自定义行为的术语,例如*,+,=等。

这可以让你编写自己的“Log”类,然后再编写

a = new Log(); // Log class overloads the + operator
a + "some string"; // Call the overloaded method - otherwise this wouldn't work because you can't normally add strings to objects.

这样做

a() || b() // be never runs if a is true

实际上叫做短路评估

===============>>#6 票数:4

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
}

===============>>#7 票数:4

请注意,&&和&之间在评估表达式的数量方面存在差异。

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

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

因此:

if (a() && b())

如果a返回true,则只调用b

但是,这个:

if (a() & b())

将始终调用ab ,即使调用a的结果为false,因此无论调用b的结果如何都知道为false

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

===============>>#8 票数:4

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

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

puts message unless message.nil?

以上将评估“message.nil?” 首先,如果它的计算结果为false(除非是在条件为false而不是true时执行除外),“puts messages”将执行,它将消息变量的内容输出到屏幕。

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

编辑:

为了使它更清晰,以上内容与以下内容相同:

unless message.nil?
  puts message
end

===============>>#9 票数:2

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

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

===============>>#10 票数:2

概念模式指的是运算符重载。 在声明中:

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

首先评估A,如果评估为false,则从不评估B. 这同样适用于

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

首先评估A,如果评估为真,则从不评估B.

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

===============>>#11 票数:1

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

===============>>#12 票数:1

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

假设你有标志,比如文件属性。 假设您已将READ定义为4,将WRITE定义为2,将EXEC定义为1.在二进制中,这是:

READ  0100  
WRITE 0010  
EXEC  0001

每个标志都有一个位设置,每个标志都是唯一的。 按位运算符允许您组合这些标志:

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

===============>>#13 票数:1

当事情全部在线时,它们是从左到右执行的。

当事物嵌套时,它们是从内到外执行的。 这可能看起来令人困惑,因为通常什么是“最里面的”在线的右侧,所以看起来它正在倒退......

例如

a = Foo( 5, GetSummary( "Orion", GetAddress("Orion") ) );

事情发生如下:

  • 使用文字"Orion"调用GetAddress
  • 呼叫GetSummary用文字"Orion"和结果GetAddress
  • 使用文字5GetSummary的结果调用Foo
  • 将此值分配给a

===============>>#14 票数:1

我喜欢猎户座的回应。 我会添加两件事:

  1. 从左到右仍然首先适用
  2. 内部到外部确保在调用函数之前解析所有参数

假设我们有以下示例:

a = Foo(5, GetSummary("Orion", GetAddress("Orion")),
           GetSummary("Chris", GetAddress("Chris")));

这是执行的顺序:

  1. GetAddress("Orion")
  2. GetSummary("Orion", ...)
  3. GetAddress("Chris")
  4. GetSummary("Chris", ...)
  5. Foo(...)
  6. 分配给a

我不能谈论C#的法律要求(虽然我在写这篇文章之前使用Mono测试了一个类似的例子),但这个顺序在Java中是有保证的。

而且为了完整性(因为这也是一个与语言无关的线程),有C和C ++等语言,除非有序列点,否则无法保证顺序。 参考文献: 12 然而,在回答线程的问题时, &&|| 是C ++中的序列点(除非重载;也请参阅OJ的优秀答案)。 一些例子:

  • foo() && bar()
  • foo() & bar()

&&情况下, foo()保证在bar()之前运行(如果后者完全运行),因为&&是一个序列点。 & case中,没有这样的保证(在C和C ++中),并且bar()实际上可以在foo()之前运行,反之亦然。

===============>>#15 票数:0

@csmba

在后续跟踪中询问为什么或何时使用And而不是AndAlso(或&而不是&&):这是一个例子:

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

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

我相信这很令人困惑。 虽然您的示例有效,但这并不是使用And的典型情况(我可能会以不同的方式编写它以使其更清晰)。 And&大多数其他语言)实际上是按位与操作。 您可以使用它来计算位操作,例如删除标志位或屏蔽和测试标志:

Dim x As Formatting = Formatting.Bold Or Formatting.Italic
If (x And Formatting.Italic) = Formatting.Italic Then
    MsgBox("The text will be set in italic.")
End If

===============>>#16 票数:0

该d编程语言是否做左到右的评价与短路容许的超载&&和“||” 运营商。

===============>>#17 票数:0

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

===============>>#18 票数:0

您可以使用与当你特别希望评估所有子表达式,很有可能是因为他们拥有你想要的副作用,即使最终的结果将是错误的 ,因此不执行你那么你的if语句的一部分。

请注意&和| 对按位掩码和布尔值进行操作,不仅适用于按位运算。 它们被称为按位,但它们是在C#中为整数和布尔数据类型定义的。

  ask by Seibar translate from so

未解决问题?本站智能推荐: