在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

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

7回复

创建(真正的)随机迷宫的最佳逻辑

我一直试图制作一个简单的游戏来测试我的逻辑,它是一个简单的迷宫,它很难看,而且到目前为止还很糟糕。 鉴于迷宫已经存在(矩阵),引擎工作得很好,它甚至可以令人愉快,但我无意绘制一堆地图,这可能是在矩阵的400(20x20)场上设置值。 不好笑。 然后我创建了一个函数来随机化它,为每个
3回复

在代码中有效地表达2x2逻辑网格

在事件处理程序中,我正在响应值的更改。 我可以访问旧值和新值,并希望根据更改的内容执行某些操作。 每个不同的结果将执行动作/函数X,Y或Z的某种组合.Z接受-1和1之间的参数。执行这些的顺序并不重要。 查看以下逻辑网格。 旧值是最左边的标签列,新值是标签的第一行: 什么是
3回复

编译嵌套的相互递归函数

我正在创建一个玩具动态语言(对javascript感到痛苦),而我的实现是在DLR之上,我认为这个问题的解决方案将是非常语言/平台无关。 编译递归函数或彼此相邻的相互递归函数我没有问题。 但是编译嵌套的相互递归函数变得更加困难。 我用来测试的示例函数如下 我认为解决这个问题
40回复

学习编写编译器[关闭]

首选语言 :C / C ++,Java和Ruby。 我正在寻找一些有用的书籍/教程,以了解如何仅出于教育目的编写自己的编译器。 我最熟悉C / C ++,Java和Ruby,因此我更喜欢涉及这三种资源之一的资源,但是任何好的资源都是可以接受的。
28回复

为什么编译器如此愚蠢?

我总是想知道为什么编译器无法弄清楚对人眼来说显而易见的简单事物。 他们做了很多简单的优化,但从来没有一点甚至有点复杂。 例如,此代码在我的计算机上大约需要6秒才能打印零值(使用java 1.6): 很明显,x永远不会改变,所以无论你多久给自己添加0,它就会保持为零。 因此编译器理论
39回复

你有没有崩溃编译器?

每个人(至少是使用编译语言的每个人)都遇到了编译错误,但是实际崩溃编译器的次数是多少? 我已经公平地分享了“内部编译器错误”,但大多数只是通过重新编译而消失了。 你有一个(最小的)代码崩溃了编译器吗?
3回复

编译编译器 - 多少次?

如果你编译一个新版本的编译器,你应该迭代地重新编译它多少次? 第一:使用旧版本[0]编译新版本的编译器[1]。 第二:使用新编译的[1]编译新版本[2],以应用新的优化并修复二进制错误,而不是旧的[0]编译器中存在的错误。 现在第三? 再次编译,使用[2]删除由于错误编译错误
6回复

识别不同语言并将它们发送到相应编译器的编译器。可能?

我在想是否有可能将asp.net,php和java连接成一个页面。 其实我现在不需要任何这样的东西。 由于某些语言的某些功能很好而且某些功能或其他一些语言都很好,所以这个想法让我大吃一惊,所以如果我将所有这些功能合并为一个,我就会想到 我的意思是,我正在创建一个页面,其中包含来自所
7回复

编译器与解释器和透明器

在我参加的reactJs会话期间,演示者使用术语转换器进行一些代码转换/移植。 在计算机系统/机器上将语言代码转换为可运行的形式时,我总是使用和听到编译器和解释器这两个术语。 对我来说,Transpiler对我来说是全新的。 有人可以帮助我理解一个Transpiler与编译器或解释器的不同
5回复

为什么C#编译器不会抛出null的逻辑比较?

我昨天吃午饭与朋友和他们抱怨null在C#。 他说null是不合逻辑的。 我决定测试他的说法,所以我测试了一些简单的逻辑命题: 检查平等似乎很简单,这就是我所期望的。 然而,更多/更少的陈述是逻辑矛盾,我觉得这真的很混乱! 这些不应该抛出? 否定操作会像您期望的那样抛出。