Wednesday, July 2, 2008

Be careful when using IIf

As I stated before, I’m a C# fan. The language itself is so beautiful that you can write clean and amazingly readable code. For example, recall the ternary expression:

(click to enlarge)

In the above example, we’re testing if the value that the variable “oneValue” contains equals “anotherValue”. If it does, CalculateSomething gets called. Otherwise, CalculateSomethingElse will be called. The result of one of these methods will be stored in the valueToPrint variable. This is the ternary expression.

Now, take a closer look at the CalculateSomethingElse method. As you can see, if we call this method an ArgumentException will be thrown, because we’re trying to convert a non-valid string to an integer. However, in the above example, the value in the “oneValue” variable equals the value in the “anotherValue” variable, so, the CalculateSomethingElse never gets called. If we run this application, everything will go as expected, with no Exceptions thrown:

(click to enlarge)

Now, VB.NET has something “similar”: the IIf. Take a look at the VB.NET version of the above example:

(click to enlarge)

The idea is basically the same as for the C# ternary expression. Remember that the CalculateSomethingElse method will throw an ArgumentException when called and the value in the “oneValue” variable equals the “anotherValue”. So, just like what happened with the C# example, you’d expect that everything would compile and run with no Exceptions (since the only method that should be called is the CalculateSomething because the test expression evaluates to true). However, this is not true. If you run the VB.NET example, you will get an ArgumentException:

(click to enlarge)

Why? Well, the IIf is actually a VB.NET function defined in the class Interaction (Microsoft.VisualBasic namespace). The problem with this is that at runtime, both the functions in the IIf get called. This is a major problem when you have large amount of work inside those methods or even something that might thrown an exception (e.g.: divide by zero). The IIf function is as follows:

(click to enlarge)


So, for those VB.NET users, the best is just to use IIf very carefully.

Tip: Compile both the examples and see the IL that was generated by the compilers.