在 C# 中对布尔值使用 &=

Posted

技术标签:

【中文标题】在 C# 中对布尔值使用 &=【英文标题】:Using &= on boolean values in C# 【发布时间】:2017-08-14 16:51:01 【问题描述】:

我在 C# 中有一个名为SendEvent 的方法,它返回一个bool,表示它是否成功。我想遍历许多对象并在它们上调用SendEvent,最后,如果所有SendEvent调用成功,则结果变量为bool,即true,以及@987654328 @如果至少有一个失败。

一开始我是这样做的:

bool result = true;
for (int i = 0; i < myObjects.Length; i++)

    result = result && myObjects[i].SendEvent();

但这将导致如果一个失败,SendEvent 将不会在后续对象上被调用,因为如果结果是 false,则不会执行 &amp;&amp; 运算符的右侧。

所以我转过身来:

bool result = true;
for (int i = 0; i < myObjects.Length; i++)

    result = myObjects[i].SendEvent() && result;

但我发现这有点难看。我可以像这样使用按位&amp;= 运算符始终执行SendEvent 调用,并设置结果的值吗?

bool result = true;
for (int i = 0; i < myObjects.Length; i++)

    result &= myObjects[i].SendEvent();

&amp;= 如何处理布尔值?它会执行操作员的双方吗?结果变量最终会是什么?

【问题讨论】:

不是&amp;=,是&amp;&amp;=&amp;= 是逻辑与的运算符。 @dcg:不,OP希望调用该事件,并且&amp;也在bools上定义。 @WillemVanOnsem 所以&amp;=&amp;&amp;= 相同,带有布尔值? @dcg: &amp;&amp;= does not exists. 这是有道理的,因为这样一个假设的&amp;&amp;= 并不能保证它背后的代码甚至会被执行。 【参考方案1】:

如您所见 here,&amp;&amp;&amp; 都为 bools 定义为“逻辑和”,但 &amp;&amp;短路: 如果第一个操作数是 false,则不会计算右侧的表达式。不管右边表达式的结果是什么,&amp;&amp; 表达式的结果将保持为false。这通常首先是“性能黑客”,但如果正确的表达式有副作用,可能会引发异常等,这是你必须考虑的事情。如果第一个操作数是 true|| 运算符也会发生同样的情况。

所以如果你想先评估双方,你确实可以使用:

result = result & myObjects[i].SendEvent();

或更短:

result &= myObjects[i].SendEvent();

背景

正如language specifications中所写:

操作

x && y  

对应操作

x & y  

除非xfalse,否则不会评估y,因为 无论y 的值是多少,AND 运算的结果都是false 是。这称为“短路”评估。

请注意,没有&amp;&amp;= 运算符(至少在我写这篇文章的时候)。这看起来合理,因为通常使用..= 运算符,您会期望首先计算操作数,然后对左侧的变量进行一些操作。当然,这完全取决于风格和品味,但我认为假设的 &amp;&amp;= 并没有给出“足够的提示”,即不会在所有情况下调用正确的操作数。 p>

【讨论】:

谢谢,这是一个很好的答案! :)【参考方案2】:

作为 LINQ 爱好者,我会这样做:

var result = (myObjects.Count(obj => obj.SendEvent()) == myObjects.Length);

如果你想打破第一个false 值的循环,它可以是:

var result = myObjects.All(obj => obj.SendEvent());

【讨论】:

@WillemVanOnsem 我的错,错过了那一行 嗯,我个人尽量避免在 Linq 中使用具有副作用的谓词...如果(例如)某些代码枚举结果两次(当然,你应该通常避免多次枚举IEnumerable&lt;T&gt; 事物,但仍然) @MatthewWatson:试图理解你所说的。你能举一个简单的例子吗?此外,这将如何影响常规的 for 循环? @dotNET:我认为这无关紧要,但马修可能想说的是,如果你有类似的东西:somelist.Where(x =&gt; SideEffect(x)),那么.Where 将被懒惰地评估。因此,您不知道何时会调用 SideEffect,这可能会导致不可预知的行为。可能需要几天时间才能最终调用 SideEffect 以获取某些 x,然后调用可能会过时,等等。通常最好避免太多副作用函数。 @WillemVanOnsem:非常感谢。我现在看到了问题。

以上是关于在 C# 中对布尔值使用 &=的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中对布尔值使用位运算符

为啥 Java 和 C# 没有到布尔值的隐式转换?

生成随机布尔值的最快方法

C# 三个布尔值,一次为真 [关闭]

正经学C#_布尔运算[布尔值与其布尔运算符]:《c#入门经典》

为啥是布尔值和布尔值