C# - Booleans Without Short-Circuiting

C# implements the boolean AND and OR operations like C/C++ with the operators && and ||.
The 'single character' versions of these (& and |) are used in both languages for bitwise AND and OR operations.
But in C# the single character versions can be used for boolean logic too, but with a twist.
The standard boolean operators (&& and ||) try to make your code as efficient as possible, by employing short-circuiting, to skip evaluation where possible.
If we have a boolean AND expression with two arguments, we know that the expression as a whole is false if one (or both) of the arguments is false. Thus when the first argument is false, the end result is known, and the second argument is never evaluated.
With OR it's the other way around: if one argument is true, the whole expression is true. Thus if the first argument evaluates to true, the second argument isn't evaluated.
Consider this sample class:


class Program
{
    static bool BooleanExpr1()
    {
        Console.WriteLine("Executing Boolean Expression 1");
        return true;
    }

    static bool BooleanExpr2()
    {
        Console.WriteLine("Executing Boolean Expression 2");
        return true;
    }

    static void Main(string[] args)
    {
        bool b = BooleanExpr1() || BooleanExpr2();
    }
}
If we run this program, only "Executing Boolean Expression 1" is printed to the console. Since BooleanExpr1 evaluates to true, the runtime immediately knows that b must be true, so it never evaluates BooleanExpr2().
This is a nice thing, since it speeds up our program, because expressions whose values have no effect on the result are skipped.
However, there are times when you do want all expressions to be evaluated for some reason.
Now you would need to write additional lines of code and introduce temporary variables to make sure all expressions are executed:
bool b1 = BooleanExpr1();
bool b2 = BooleanExpr2();
bool b = b1 || b2;
But C# gives us the single-character boolean operators. What they do is equal to the two-character boolean operators, but without the short-circuiting. All parts of the boolean expressions are evaluated, no matter if that is neccessary or not.
Thus, the three lines of code above can be reduced to
bool b1 = BooleanExpr1() | BooleanExpr2();
And we see "Executing Boolean Expression 1 Executing Boolean Expression 2" in the console.

No comments:

Post a Comment