Question

 class Program
 {
  static void Main(string[] args)
  {
   bool success = true;
   int[] array = { 10, 15, 20 };
   foreach (var i in array)
    success = success && SynchronizeAccount(i);
  }

  static bool SynchronizeAccount(int i)
  {
   Console.WriteLine(i);
   return false;
  }
 }

Output is 10. After first step 'success' becomes false and never will be true, so c# stops loop execution after first iteration. But I need SIDE effect of SynchronizeAccount, not 'success' value.

Was it helpful?

Solution

This is not a bug, as in nearly all programming languages C# evaluates && lazily - if the left operand is already false, the whole expression can never become true, so it's not required anymore to evaluate the right operand of the expression.

Flip the operands or change to success & SynchronizeAccount to force evaluation of both operands.

Note that it's a unique feature of C# that you can apply both & and && to boolean values - in most other languages including Java and PHP a single ampersand (&) is the bitwise AND, which often provides completely different results.

OTHER TIPS

This is not a bug, this is normal behavior. The && operator will only evaluate the right side of the operator if the left side evaluate to true:

The conditional-AND operator (&&) performs a logical-AND of its bool operands, but only evaluates its second operand if necessary.

So after the first iteration, success evaluates to false, and SynchronizeAccount does not get called again.

If you want to evaluate SynchronizeAccount regardless of what it returns, use & operator instead:

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

Or more simply:

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

Or perhaps use a little Linq:

bool success = array.Aggregate(true, (b, i) => b & SynchronizeAccount(i));

This is not a bug, It is called Short-circuit evaluation. If you really need to get the second method to work too, us & instead of &&

I wouldn't treat this as a bug; it looks like simply an optimization. "&&" is short-circuit so compiler is permitted to optimize the method calling if its result isn't needed.

You could try rewriting this like


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

Consider removing success from your loop.

The other answers are awesome for explaining & vs &&, but I'm not sure what purpose success even has in your code. Since you intend to ignore it and iterate through all the items in array anyway, just call SynchronizeAccount inside your foreach loop and ignore the returned value.

static void Main(string[] args)
{
    int[] array = { 10, 15, 20 };
    foreach (var i in array)
        SynchronizeAccount(i);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top