在 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
,则不会执行 &&
运算符的右侧。
所以我转过身来:
bool result = true;
for (int i = 0; i < myObjects.Length; i++)
result = myObjects[i].SendEvent() && result;
但我发现这有点难看。我可以像这样使用按位&=
运算符始终执行SendEvent
调用,并设置结果的值吗?
bool result = true;
for (int i = 0; i < myObjects.Length; i++)
result &= myObjects[i].SendEvent();
&=
如何处理布尔值?它会执行操作员的双方吗?结果变量最终会是什么?
【问题讨论】:
不是&=
,是&&=
。 &=
是逻辑与的运算符。
@dcg:不,OP希望调用该事件,并且&
也在bool
s上定义。
@WillemVanOnsem 所以&=
与&&=
相同,带有布尔值?
@dcg: &&=
does not exists.
这是有道理的,因为这样一个假设的&&=
并不能保证它背后的代码甚至会被执行。
【参考方案1】:
如您所见 here,&
和 &&
都为 bool
s 定义为“逻辑和”,但 &&
将 短路: 如果第一个操作数是 false
,则不会计算右侧的表达式。不管右边表达式的结果是什么,&&
表达式的结果将保持为false
。这通常首先是“性能黑客”,但如果正确的表达式有副作用,可能会引发异常等,这是你必须考虑的事情。如果第一个操作数是 true
,||
运算符也会发生同样的情况。
所以如果你想先评估双方,你确实可以使用:
result = result & myObjects[i].SendEvent();
或更短:
result &= myObjects[i].SendEvent();
背景
正如language specifications中所写:
操作
x && y
对应操作
x & y
除非
x
是false
,否则不会评估y
,因为 无论y
的值是多少,AND 运算的结果都是false
是。这称为“短路”评估。
请注意,没有&&=
运算符(至少在我写这篇文章的时候)。这看起来合理,因为通常使用..=
运算符,您会期望首先计算操作数,然后对左侧的变量进行一些操作。当然,这完全取决于风格和品味,但我认为假设的 &&=
并没有给出“足够的提示”,即不会在所有情况下调用正确的操作数。 p>
【讨论】:
谢谢,这是一个很好的答案! :)【参考方案2】:作为 LINQ 爱好者,我会这样做:
var result = (myObjects.Count(obj => obj.SendEvent()) == myObjects.Length);
如果你想打破第一个false
值的循环,它可以是:
var result = myObjects.All(obj => obj.SendEvent());
【讨论】:
@WillemVanOnsem 我的错,错过了那一行 嗯,我个人尽量避免在 Linq 中使用具有副作用的谓词...如果(例如)某些代码枚举结果两次(当然,你应该通常避免多次枚举IEnumerable<T>
事物,但仍然)
@MatthewWatson:试图理解你所说的。你能举一个简单的例子吗?此外,这将如何影响常规的 for
循环?
@dotNET:我认为这无关紧要,但马修可能想说的是,如果你有类似的东西:somelist.Where(x => SideEffect(x))
,那么.Where
将被懒惰地评估。因此,您不知道何时会调用 SideEffect
,这可能会导致不可预知的行为。可能需要几天时间才能最终调用 SideEffect
以获取某些 x
,然后调用可能会过时,等等。通常最好避免太多副作用函数。
@WillemVanOnsem:非常感谢。我现在看到了问题。以上是关于在 C# 中对布尔值使用 &=的主要内容,如果未能解决你的问题,请参考以下文章