在C#中使用&= on boolean值

Hel*_*ena 3 c# boolean operators short-circuiting

我在C#中有一个方法,SendEvent它返回一个bool表示它是否成功的方法.我想循环遍历许多对象并调用SendEvent它们,最后,有一个结果变量是a bool,即true如果所有SendEvent调用都成功,并且false至少有一个失败.

起初我这样做了:

bool result = true;
for (int i = 0; i < myObjects.Length; i++)
{
    result = result && myObjects[i].SendEvent();
}
Run Code Online (Sandbox Code Playgroud)

但是SendEvent如果一个失败,那将导致后续对象不会被调用,因为&&如果结果是,则不会执行操作符的右侧false.

所以我把它转过来:

bool result = true;
for (int i = 0; i < myObjects.Length; i++)
{
    result = myObjects[i].SendEvent() && result;
}
Run Code Online (Sandbox Code Playgroud)

但我觉得有点难看.我可以使用按位运算&=符来始终执行SendEvent调用,并设置结果的值,像这样?

bool result = true;
for (int i = 0; i < myObjects.Length; i++)
{
    result &= myObjects[i].SendEvent();
}
Run Code Online (Sandbox Code Playgroud)

如何&=处理布尔值?它会执行运营商的两面吗?什么会在结果变量中结束?

Wil*_*sem 8

正如可以看这里,&&&被定义为bool小号为" 逻辑和 ",但&&短路:在情况下,第一操作数是false在右边的表达不会被评估.无论右边表达式的结果是什么,表达式的结果都&&将保留false.这通常是一个"性能黑客",但如果正确的表达有副作用,可能会抛出异常,等等,这是你必须要考虑的事情.||如果第一个操作数是,则运算符也会发生相同的情况true.

因此,如果您想先评估双方,您确实可以使用:

result = result & myObjects[i].SendEvent();
Run Code Online (Sandbox Code Playgroud)

或更短:

result &= myObjects[i].SendEvent();
Run Code Online (Sandbox Code Playgroud)

背景

正如语言规范中所写:

操作

x && y  
Run Code Online (Sandbox Code Playgroud)

对应于操作

x & y  
Run Code Online (Sandbox Code Playgroud)

不同之处在于,如果xfalse,y不评估,由于与操作的结果是false无论什么价值y 是.这被称为" 短路 "评估.

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


dot*_*NET 6

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

var result = (myObjects.Count(obj => obj.SendEvent()) == myObjects.Length);
Run Code Online (Sandbox Code Playgroud)

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

var result = myObjects.All(obj => obj.SendEvent());
Run Code Online (Sandbox Code Playgroud)

  • 嗯,我个人试着避免使用在Linq中有副作用的谓词...如果(例如)某些代码枚举结果两次(当然,你应该避免枚举`IEnumerable <T>)会导致令人惊讶的事情.事情一般多次,但仍然) (2认同)