C# 布尔型,不计算表达式的两侧

C# 布尔型,不计算表达式的两侧,c#,boolean-expression,side-effects,C#,Boolean Expression,Side Effects,输出为10。在第一步之后,“success”变为false并且永远不会为true,所以c在第一次迭代后停止循环执行。但是我需要SynchronizeeAccount的副作用,而不是'success'值。这不是一个bug,因为在几乎所有的编程语言中,C都是惰性求值的&如果左操作数已经为false,那么整个表达式就永远不会为true,因此不再需要求值表达式的右操作数 翻转操作数或更改为success&synchronizeeAccount以强制计算两个操作数 请注意,这是C语言的一个独特功能,您可以

输出为10。在第一步之后,“success”变为false并且永远不会为true,所以c在第一次迭代后停止循环执行。但是我需要SynchronizeeAccount的副作用,而不是'success'值。

这不是一个bug,因为在几乎所有的编程语言中,C都是惰性求值的&如果左操作数已经为false,那么整个表达式就永远不会为true,因此不再需要求值表达式的右操作数

翻转操作数或更改为success&synchronizeeAccount以强制计算两个操作数


请注意,这是C语言的一个独特功能,您可以对布尔值同时应用&和&&在大多数其他语言(包括Java和PHP)中,一个符号&是按位and,它通常提供完全不同的结果。

这不是错误,这是正常行为。仅当左侧评估为真时,才会评估操作员的右侧:

条件AND运算符&&对其布尔操作数执行逻辑AND运算,但仅在必要时计算其第二个操作数

因此,在第一次迭代之后,success的计算结果为false,并且SynchronizeeAccount不会再次被调用

如果要计算SynchronizeeAccount,而不管它返回什么,请改用:

或者更简单地说:

foreach (var i in array)
    success = success & SynchronizeAccount(i);
或者使用一点Linq:

foreach (var i in array)
    success &= SynchronizeAccount(i);

这不是一个bug,它被称为。如果你真的需要让第二种方法也起作用,我们&而不是&

我不会把它当作一个bug;它看起来只是一个优化是短路的,因此如果不需要方法调用的结果,则允许编译器优化方法调用

你可以试着像这样重写

bool success = array.Aggregate(true, (b, i) => b & SynchronizeAccount(i));
考虑从循环中删除成功

其他答案对于解释&vs&&来说是非常棒的,但我不确定成功在代码中有什么目的。因为您打算忽略它并遍历数组中的所有项,所以只需在foreach循环中调用synchronizeeAccount并忽略返回的值


foreach (var i in array) {
  if(!SynchronizeAccount())
    success = false;
}

@GrantWinney不,这肯定是编译器中的一个bug;你真的认为你在编译器中发现了一个bug,是吗?在彩票中赢得100万美元而没有购买一笔财富的可能性更大。当我看到这篇文章的第一个标题时,我真的被吓坏了,但是当我浏览这篇文章时,我就像是在说不!现在这个标题很合适!正确解释success&SynchronizeeAccount和success&SynchronizeeAccount之间的差异。注意,在原始问题中也可以使用复合赋值,因此success&=SynchronizeAccount;。不仅允许优化,还要求优化。就像我说如果x!=null&&x.IsNew{…},如果左侧为false,则要求不对&&运算符的右侧求值。在这种情况下,求值右侧将导致异常。@JeppeStigNielsen您完全正确;但我已经回应了“停止循环执行”这句话。它可以是简单的主题启动者意见,但是,如果设置成功是循环体的唯一操作,编译器可以通过停止整个循环来优化它。这不会改变任何可见的结果,除了花费的时间。

foreach (var i in array) {
  if(!SynchronizeAccount())
    success = false;
}
static void Main(string[] args)
{
    int[] array = { 10, 15, 20 };
    foreach (var i in array)
        SynchronizeAccount(i);
}