为什么会在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 =

或者,如果对someOtherCaseexpression式没有副作用,请使用Jakub Konecki的解决scheme: someCase || someOtherCase someCase || someOtherCase

有趣的 – 看起来像是在做同样的事情:

 tmp = tmp | true; 

这将始终将tmp设置为true。

foo |= truefoo = foo | true的简短版本 foo = foo | true

实际的代码可以被重写为

 bool tmp = false; tmp |= someCase; tmp |= someOtherCase; 

或者甚至更好

 someCase || someOtherCase 

和其他op =运算符一样, x |= y是等价的(除了多重评估的副作用)到x = x | y x = x | yif (!x) x = y;这是一种简洁的写法if (!x) x = y; 或者if (y) x = true;

然而,在右边有一个常数是没有意义的。

  • x |= true更直接写为x = true
  • x |= falsex不变。

他们为什么要这样做。

一些可能的解释是:

  • 这是一个错字:他们的意思是写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; 

我同意这里的其他海报…!

更多信息在这里