“如果(a()&& b!= null)”将“a()”总是被评估?
我有这样的代码:
if (a() && b != null) { b.doSomething(); }
即使b
为null
我也需要a()
副作用。 它由C#保证吗? 或者如果b
为null
C#可能会省略a()
调用?
是的, a()
将总是被评估。
由于条件是从左到右计算的,因此总是会计算a()
,但只有当a()
返回true
才会计算b != null
。
以下是C#语言规范3.0版本中的一个精确的规范参考。 我的重点和精力。
7.11.1布尔条件逻辑运算符
当
&&
或||
的操作数 是bool
types的操作处理如下:
- 操作
x && y
被评估为x ? y : false
x ? y : false
换句话说, 首先评估x
并将其转换为booltypes。 然后, 如果x
为真 ,则评估y并转换为typesbool,并且这成为操作的结果。 否则,操作的结果是错误的。
是的,expression式从左到右进行评估; 所以a()
将总是被调用。
请参阅C#语言规范 (ECMA 334,第8.5段):
除赋值运算符外,所有二元运算符都是左关联的,这意味着操作从左到右执行。 例如,x + y + z被评估为(x + y)+ z。
条件从左到右进行评估。 所以a()
总是被执行,但是根据a()
的结果, b
可能不被计算。
a()
将始终被评估。 b != null
只会在a()
计算结果为true时被评估。
这被称为短路评估 。
&&的左侧总是被评估。 只有在左边为真的情况下才会评估右侧。 所以你应该没问题。
根据MSDN :
操作
x && y对应于操作
x和y除外,如果x为假,则不计算y,因为无论y的值是多less,AND运算的结果都是false。 这被称为“短路”评估。
if语句中的逻辑条件由两个逻辑运算符组成,首先是a()
,它总是被赋值。
a()将总是被调用,因为它是检查if语句的第一件事情,即使b为null。
如果编译器推断进一步的评估不会修改结果,那么布尔expression式可能会被完全评估或部分被完全评估。
if (a() || b()) c();
如果依赖b()的副作用,那么如果特定的编译器实现进行智能布尔评估,则得不到您想要的结果。 我不确定关于评估布尔expression式的标准是什么,但是如果你想要你的源代码的可读性,你最好把它拼出来。 这将增加可读性。
if (a()) { b(); c(); } else if (b()) c();
由于从左到右评估条件,因此总是会评估a()
。 而且,由于您使用了短路AND(&&),如果a()
返回false,则不会评估b != null
。 如果您希望评估两个条件a()
是否返回true或false,请使用&
运算符。
除了最好的答案:
(x && y)
评估:
如果x评估为false ,则不会评估y。
(x || y)
评价:
如果x评估为真 ,则不会评估y。
在任何情况下,第一个操作数总是被评估。 在第二个操作数中必须特别注意副作用。
是的,但是“你的代码工作并不重要,你的代码是可以理解的 ,这一点很重要” 。
我喜欢这样做:
bool val = a(); if (val && b != null) { b.doSomething(); }
这取决于你想要的操作的优先级。 是的,从左到右评估意味着一个()总是在其他之前执行。 如果你想让b!= null总是评估交换自己的位置。
条件为真时,&&条件运行。
所以a()函数在b不等于null时呈现。
这是所有亲的基本