为什么会在C#中使用布尔值的| =运算符?
例:
我们发现这是一些供应商编写的代码,我们正试图弄清楚为什么他们会这样做。
bool tmp = false; if (somecase) tmp = true; if (someOtherCase) tmp |= true;
完全没有理由。 布尔值|= true
将始终为true
。 这是有人试图看中,或忘记布尔逻辑=)
将其更改为tmp = true;
。
也许其中一个布尔文本是一个variables,他们只是没有想到改变操作符时,他们改变操作数。 显然这个逻辑是等价的。
更可能的是,他们认为在第二种情况下,他们想保留评估第一个“如果”条件的结果。 当然,这是错误的推理。
一个更简单的等同声明:
bool tmp = somecase | someOtherCase;
编辑
正如pickypg所指出的那样,这个陈述可能会让人困惑,因为大多数人都不期望|
与布尔值,许多人不会注意到,或不会考虑副作用的影响。 明确的最好的方法(如果确实有副作用)将是minitech的解决scheme:只要改变|=
to =
。
或者,如果对someOtherCase
expression式没有副作用,请使用Jakub Konecki的解决scheme: someCase || someOtherCase
someCase || someOtherCase
。
有趣的 – 看起来像是在做同样的事情:
tmp = tmp | true;
这将始终将tmp设置为true。
foo |= true
是foo = foo | true
的简短版本 foo = foo | true
。
实际的代码可以被重写为
bool tmp = false; tmp |= someCase; tmp |= someOtherCase;
或者甚至更好
someCase || someOtherCase
和其他op =运算符一样, x |= y
是等价的(除了多重评估的副作用)到x = x | y
x = x | y
。 if (!x) x = y;
这是一种简洁的写法if (!x) x = y;
或者if (y) x = true;
。
然而,在右边有一个常数是没有意义的。
-
x |= true
更直接写为x = true
-
x |= false
叶x
不变。
他们为什么要这样做。
一些可能的解释是:
- 这是一个错字:他们的意思是写
tmp = true;
而不是tmp |= true;
,但从来没有注意到它,因为他们的程序发生按预期工作。 - RHS最初是一个variables,它被replace为常量而不改变代码。
-
tmp
最初是一个位域 (对于这个位域更有意义),后来减less到一个位数。
最终的结果将是“如果任何一个情况是真的,结果是真实的。” 因为||
,所以没有理由必须使用操作符 在一个if
将工作以及。
一个聪明的编译器可以避免在这种情况下的分配,但它可能不会因为它不应该短路一个按位操作。 无论如何,这似乎是一个微观优化。 实际上,我怀疑这是作者使用位标记(或者他/他不明白它是如何工作的)的一个保留模式。 这会更好,因为:
bool tmp = somecase || someOthercase;
(然后如果只使用一次就内联临时)
请注意,使用标志时,这是有道理的。
#define CONDITION_ONE 0x01 #define CONDITION_TWO 0x02 int temp = 0; if (somecase) { temp = CONDITION_ONE; } if (someOthercase) { temp |= CONDITION_TWO; }
它是一个使用| =赋值运算符的expression式。 检查MSDN
对于bools来说不是那么多
然而,对于位标,这可以允许这样的代码:
int flags=0; flags|=READ; //flags|=UPDATE; foo(arg,flags);
这允许一些标志很容易被注释掉(并且使得使用的标志更加可读的IMO)
这相当于
tmp = tmp | true;
编辑:这是相等的
tmp = true;
我同意这里的其他海报…!
更多信息在这里