C#决定完全将整数操作与布尔操作分离。例如,您不能这样做:if(x & 4)
,而必须这样做:if((x & 4) != 0)
以明确地从整数转换为布尔值。
这符合使用C及其前身超过40年的经验,人们通常会犯错,例如对两个具有真值true
的值进行 & 操作,由于它们都是非零值,但没有任何非零位重叠,因此得到 false
。
C和C++都在其历史的晚期引入了bool
类型,以添加更明确的区别,即表示数字或位模式的整数和我们只关心真值的值,但必须与旧代码兼容。 C#可以更加明确。
考虑到这一点,C#的!
和~
与C中完全相同,只是某些东西不再有意义:
在C中,!
表示取反,将0(false)转换为1(true),将所有非零值(true)转换为0(false)。在C#中,这只适用于bool
,而不适用于int
。
在C中,~
产生一的补数;它产生一个值,其中每个1位都变为0,每个0位都变为1(例如,0xFFFFFFFF变为0,0xF0F0F0F0变为0x0F0F0F0F等)。在C#中,这适用于int
,但不适用于bool
。
如果要执行类似于!someInteger
的操作,请在C#中执行someInteger == 0
。
编辑:
值得注意的是,由于运算符被分为“按位”('&', '|', '~')和“布尔”('&&','||'和'!'),有时可能会产生一些混淆。但这种区分并不完全正确。
最后三个运算符确实只在布尔上下文中有意义,在C#中,由于布尔和整数值之间有更严格的分离,它们不再适用于整数。
'~'确实没有在布尔上下文中使用的意义('~x'其中'x'为真将产生一个仍然为真的'x',4294967295次中有4294967294次),因此在C#中它不再适用于bool类型。
'&'和'|'保留了布尔用法。如果'A()'和'B()'各自返回
bool
,那么
A() && B()
仅在
A()
为false时才调用
B()
(即,“短路”),而
A() & B()
则总是先调用两个方法,然后进行
∧
布尔运算。这往往很少见,因为:
大多数情况下调用B()
只是浪费时间,并且短路可以带来从巨大的性能提升(如果B()
很昂贵)到没有任何影响但我们也没有损失任何东西的效果,所以应该养成这个习惯。(但是请考虑,如果B()
非常便宜,则总是调用它的成本可能比分支还要便宜,特别是如果预测错误,请参见下面的注释。)
有时候&&
是强制性的,例如x != null && x.Length != 0
,不短路将在第二个参数上抛出异常。
如果确保两个方法都被调用非常重要,则最好在单独的语句中进行编码,以向其他开发人员(或稍后返回时自己)清晰地表明这一点。
但如果我们要讨论具有布尔值和整数参数的运算符之间的区别,我们应该包括对 |
和 &
的布尔使用,因为它们确实会出现(有时是由于错字!),如果人们错误地将"位运算符"和"布尔运算符"分开,并忘记有两个符号被同时用作这两种运算符,那么它们可能会引起混淆。
true == 0x00000001
,当你运行~0x01
和!0x01
时,差异应该更加明显。 - ssube