为啥要在 C# 中对布尔值使用 |= 运算符?
Posted
技术标签:
【中文标题】为啥要在 C# 中对布尔值使用 |= 运算符?【英文标题】:Why would one use the |= operator on a boolean value in C#?为什么要在 C# 中对布尔值使用 |= 运算符? 【发布时间】:2012-04-12 04:26:00 【问题描述】:例子:
我们发现这是一些供应商编写的代码,我们正试图弄清楚他们为什么要这样做。
bool tmp = false;
if (somecase)
tmp = true;
if (someOtherCase)
tmp |= true;
【问题讨论】:
右边真的是常数true
吗?在布尔值上使用|=
是完全合理的,而很少使用|= true
。
您知道,即使msdn 在其示例中列出了一个布尔值和|=
运算符...
【参考方案1】:
完全没有理由。布尔值 |= true
将始终为 true
。这是一个想花哨的人,或者忘记布尔逻辑=)
将其更改为tmp = true;
。
【讨论】:
感谢您在经过几个测试程序后我得出了这个结论。这就是我问的原因.. 不安全。 @code4life:false | true
仍然是 true
... 你是不是也忘记了你的布尔逻辑?
@code4life:好吧,如果是这样呢?那么它在“tmp |= true;”之后的状态是什么?
tmp |= someOtherCase;会更有意义。也许它是这样开始的,然后不小心被转换成带有 if 的更复杂的形式。
|= false
也无用:这是一个空操作。【参考方案2】:
也许其中一个布尔文字曾经是一个变量,他们只是在更改操作数时没有考虑更改运算符。显然逻辑是等价的。
更有可能的是,他们认为在第二种情况下,他们希望保留评估第一个“if”条件的结果。当然,这是错误的推理。
一个更简单的等效语句:
bool tmp = somecase | someOtherCase;
编辑
正如 pickypg 所指出的,这种说法可能会令人困惑,因为大多数人并不期望 |
具有布尔值,而且许多人不会注意到它,或者不会考虑副作用的含义。最好的表达方式(如果确实有副作用)是 minitech 的解决方案:只需将 |=
更改为 =
。
或者,如果 someOtherCase
表达式没有副作用,请使用 Jakub Konecki 的解决方案:someCase || someOtherCase
。
【讨论】:
这就是我们的想法……或者可能是幸运的类型。 我怀疑那是原始代码,但即使这样也应该转换为bool tmp = somecase || someOtherCase;
以让短路完成它的工作。如果您想要副作用,那么您很可能会通过单行代码来破坏可读性,特别是通过隐式关联在那时只能松散关联的两种方法(因为第一种方法不会通过“失败”来阻止第二种方法) " 或 false
代表的任何内容)。
@pickypg 我同意在代码中加上|
会降低可读性。还有很大的可能有人会在某个时候将|
“纠正”为||
。这两者都是正确的,因为使用带有布尔值的|
并不是真正地道的 C#。我觉得这很可惜,但没有什么可做的。【参考方案3】:
有趣 - 看起来它正在做同样的事情:
tmp = tmp | true;
这将始终将 tmp 设置为 true。
【讨论】:
【参考方案4】:foo |= true
是foo = foo | true
的缩写。
实际代码可以改写为
bool tmp = false;
tmp |= someCase;
tmp |= someOtherCase;
甚至更好
someCase || someOtherCase
【讨论】:
小问题:如果 someOtherCase 有副作用,someCase | someOtherCase
会保留它们,而someCase || someOtherCase
不会。【参考方案5】:
与其他 op= 运算符一样,x |= y
与 x = x | y
等效(除了多重评估的副作用)。这是if (!x) x = y;
或if (y) x = true;
的简洁写法。
但是,在右侧有一个 常量 没有任何意义。
x |= true
更直接地写成x = true
x |= false
保持 x
不变。
他们为什么要这样做。
一些可能的解释是:
这是一个错字:他们本来打算写tmp = true;
而不是 tmp |= true;
,但从未注意到,因为他们的程序恰好按预期运行。
RHS 原本是一个变量,被替换为常量true
,没有另外更改代码。
tmp
最初是 bitfield(|=
更有意义),后来被简化为一个位。
【讨论】:
【参考方案6】:最终的结果将是“如果任何一种情况为真,则结果为真”。不过,您没有理由必须使用运算符,因为 if
中的 ||
也可以正常工作。
【讨论】:
如果someOtherCase
有副作用,您需要使用|
而不是||
来保留它们。【参考方案7】:
一个聪明的编译器可以避免这种情况下的赋值,尽管它可能不会因为它不应该短路按位操作。无论如何,这似乎是一种微优化。实际上,我怀疑这是作者使用位标志的一种保留模式(或者他/她只是不明白它是如何工作的)。最好是:
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;
【讨论】:
这不会保留someOtherCase
的副作用,如果有任何要保留的话。
@phoog - 这是真的。如果 case 是函数或包含语句,那么使用惰性求值就不一样了,它们不应该合并。
您可以将它们与|
运算符结合使用。
@phoog 那将是最纯粹的邪恶。 IMO,根据读者区分按位或和逻辑或来确定语句的评估(在布尔值上)是最糟糕的编码魔法。我宁愿将条件拆分并在两个语句中进行评估,以明确期望是什么。我一直使用的规则是你只对布尔变量使用逻辑运算符。
我同意你的看法;两个运算符之间的细微差别使得很容易误读一个。但是,您的术语与 Microsoft 的不一致;他们将两个运算符都归类为逻辑运算符,并区分按位逻辑和布尔逻辑:msdn.microsoft.com/en-us/library/6a71f45d(v=vs.100).aspx【参考方案8】:
对于布尔值不是很多
但是对于位标志,这可以允许这样的代码:
int flags=0;
flags|=READ;
//flags|=UPDATE;
foo(arg,flags);
这允许一些标志很容易被注释掉(并使使用的标志在 IMO 中更具可读性)
【讨论】:
【参考方案9】:这相当于
tmp = tmp | true;
编辑: 等于
tmp = true;
我同意这里的其他海报......!
更多信息here
【讨论】:
【参考方案10】:它是一个使用 |= 赋值运算符的表达式。检查MSDN
【讨论】:
是的,我查看并理解它只是没有意义,他们在我拥有的代码中使用它。以上是关于为啥要在 C# 中对布尔值使用 |= 运算符?的主要内容,如果未能解决你的问题,请参考以下文章
正经学C#_布尔运算[布尔值与其布尔运算符]:《c#入门经典》