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

Sei*_*bar 18 c# language-agnostic compiler-construction logic

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

例:

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

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

myDt != null
Run Code Online (Sandbox Code Playgroud)

要么:

myDt.Rows.Count > 0
Run Code Online (Sandbox Code Playgroud)

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


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

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

Zom*_*eep 16

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


Bri*_*ahy 9

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

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

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

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

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


OJ.*_*OJ. 8

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

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

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

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


csm*_*mba 6

vb.net

if( x isNot Nothing AndAlso x.go()) then
Run Code Online (Sandbox Code Playgroud)
  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()
Run Code Online (Sandbox Code Playgroud)

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

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


Ori*_*rds 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.
Run Code Online (Sandbox Code Playgroud)

这样做

a() || b() // be never runs if a is true
Run Code Online (Sandbox Code Playgroud)

实际上叫做短路评估