04 Jun 2009

I’m often amazed that most programmer don’t know that in C# and in Java you can use the simple & and | as logical operators. It seems than most people don’t event know that they exist!

But what’s the difference between these simple and double logical operators?

Back To Basics

Let’s see in the C# language specifications:

The result of x & y is true if both x and y are true. Otherwise, the result is false.

The result of x | y is true if either x or y is true. Otherwise, the result is false.

Now let’s have a look in Java language specifications:

For &, the result value is true if both operand values are true; otherwise, the result is false.

For |, the result value is false if both operand values are false; otherwise, the result is true.

It’s pretty clear, it does what most of the people would expect them to do, and and or operations.

But, then, what are those && and || that most developers use everywhere, wasting bytes like there’s now tomorrow?

Again, specifications are there to give full explanations.

In C#:

The && and || operators are conditional versions of the & and | operators:

  • The operation x && y corresponds to the operation x & y, except that y is evaluated only if x is true.
  • The operation x || y corresponds to the operation x | y, except that y is evaluated only if x is false.

And in Java:

The && operator is like & (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is true.

The || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.

Tadaaaam! Now it makes perfect sense, doesn’t it? These operators that most of the people use everywhere are smart and only evaluate the right-side if it is of any use (if left-hand side is true for and, if left-hand side is false for or).

So, let’s give a small example of how this can be useful. Let’s pretend you have an object that has a member that can be null. With these operators, you can test it without any fear of the dreaded NullReferenceException or NullPointerException. Here is a small piece of C# code that shows the point:

var p = new Parent { Name = "Father" };
p.Childs = new Person[] { new Person() { Name = "Son" } };

if (p.Childs != null && p.Childs.ElementAt(0).Name != null)
{
    Console.WriteLine("First Child's name: {0}", 
        p.Childs.ElementAt(0).Name);
}

If Child collection was left null, this code would still work even though p.Childs.ElementAt(0) would normally throw an ArgumentNullException. As p.Childs != null returns false, the right-hand operand is not evaluated so no exception is thrown.

Now, as you may say “Well in this case, why does it matter? Let’s use && and || everywhere, so we make no mistake!”. Technically, it is true. However, as one of my University teacher said:

Les gens qui utilisent les opérateurs conditionnels booléens partout sont des gens qui ne savent pas ce qu'ils font.

Translation: “Peoples who use conditional logical operators everywhere are peoples that don’t know what they're doing”.

Of course, his point was that you should understand the code you are writing and that you should know when which part of an expression can be evaluated. I have no clue if there is a performance gain when using non conditional operators, nor if there is any compiler optimization of any kind.

The Third Operator

There is also a third operator in both languages: ^.

In C#:

The result of x ^ y is true if x is true and y is false, or x is false and y is true. Otherwise, the result is false. When the operands are of type bool, the ^ operator computes the same result as the != operator.

In Java:

For ^, the result value is true if the operand values are different; otherwise, the result is false.

I’v never seen this operator used. As pointed in C# specification, this operator has the same result as the != operator.

And, of course, it doesn’t make any sense to have a ^^ operator, as both operand have to be evaluated in all the cases…



blog comments powered by Disqus