"if(a()&& b!= null)"将"a()"始终被评估?

jav*_*red 47 c#

我有这样的代码:

if (a() && b != null) {
    b.doSomething();
}
Run Code Online (Sandbox Code Playgroud)

a()即使b是,我也需要副作用null.它是由C#保证的吗?或者C#可以省略a()呼叫,如果bnull

Aak*_*shM 118

是的,a()将始终进行评估.

由于条件是从左到右计算的,因此a()将始终进行评估,但b != null仅在a()返回时 进行评估true.

以下是C#语言规范3.0版的精确规范参考.我的重点和精神.

7.11.1布尔条件逻辑运算符

当[ &&或] ||类型的操作数操作bool如下处理时:

  • 该操作x && y被评估为x ? y : false.换句话说,x第一评估并转换为bool类型.然后,如果x为true,则计算y并将其转换为bool类型,这将成为操作的结果.否则,操作的结果为false.

  • 为什么这个答案很差?当规范明确地以简洁易懂的方式给出答案时? (35认同)
  • @Konerak:您能为我们发布您的"人性化英语"答案吗?作为一个匈牙利人,我认为该规范的片段是非常清晰和可读的,任何在这种情况下不理解它的程序员都应该认真考虑开始一个阅读理解是可选的职业.此外,如果规范不明确,可以明确答案是否正确? (11认同)
  • 只是粘贴规范是一个糟糕的答案.由于这已经是公认的答案,我在规范的顶部添加了答案.+1 (10认同)
  • *差*有点严重,但StackOverflow可以比复制粘贴规范做得更好.解释人类英语,链接到规范(仍然缺少那个)... (5认同)
  • @GyörgyAndrasek:在这个例子中,规范确实非常清楚,但他的补充也是:他回答了实际问题('是')并使用了问题中的变量/名称.当人们不习惯阅读规范时,人们有时难以将规范应用于具体情况.你是对的:规范应该足够了,但有时对于某些人来说,它并不是马上就可以了. (4认同)

Jan*_*oom 31

是的,表达式从左到右进行评估; 所以a()永远都会被召唤.

参见C#语言规范(ECMA 334,第8.5段):

除赋值运算符外,所有二元运算符都是左关联运算符,这意味着操作从左到右执行.例如,x + y + z被评估为(x + y)+ z.

  • 这可能太小,但左联结适用于'x + y + z` - 它并不表示在`(x + y)``x`被评估为第一或第二.这将是另一节`:)` (4认同)
  • 那根本不小,Kobi,这一段与这个问题无关!为了完整性:如果C#规范没有提到任何其他内容,这个评估顺序也适用于`x + y + z`:`y`,`x`,`x + y`,`z`,`( x + y)+ z`.事实上,如果不受规范的限制,第8.5段仍然允许首先评估"z"; 本段仅涉及操作员对彼此的评价顺序. (2认同)

Lin*_*een 17

条件从左到右进行评估.所以a()总是执行,但b 可能不会根据结果来评估a().


Sea*_*ean 13

a()将永远被评估.b != null只有在a()评估为真时才会被评估.

这被称为短路评估.


Jay*_*Jay 6

始终评估&&的左侧.只有左边为真,才会评估右边.所以你应该没事.


npi*_*nti 5

根据MSDN:

操作

x && y对应于操作

x&y除了如果x为假,则不计算y,因为无论y的值是什么,AND运算的结果都是假的.这被称为"短路"评估.