Be careful of your conditionals!

Doug Reilly posts about C#'s conditional operator in response to Rachel's post on VB.NET's IIf() statement.

One important distinction needs to be made between these two -- and it has serious implications for the VB.NET version. C#'s conditional operator is built into the language. When C# compiles the conditional operator into IL, it emits IL very similar to an if/then/else statement. VB.NET's IIf is a library function in the Microsoft.VisualBasic namespace. When VB.NET compiles a call to IIf, it has to evaluate all three parts of the IIf (the condition, the true part and the false part) and then send them to the IIf function for evaluation. This presents a huge problem in a scenario such as:

Dim info As String = IIf(foo Is Nothing, "EMPTY", foo.data)

Guess what happens? VB.NET emits IL to:

  • Evaluate the "foo is Nothing" conditional
  • Load the string "EMPTY"
  • Load the value of foo.data

How can you load the value of foo.data if foo is null? You can't! Can you say "NullReferenceException"?

The behavior in VB.NET is the same as it's been in past versions of VB. This is probably to preserve some backwards compatibility with code that may call a function to return the true and false parts such as:

Dim info As String
info = IIf(foo Is Nothing, GetDefaults(), GetObjInfo(foo))

In VB.NET (as well as previous versions of VB), you know both "GetDefaults" and "GetObjInfo" would be called when this statement is hit. GetObjInfo would, of course, need to be designed to handle the possibility of a null parameter. But if VB.NET were to break this behavior and work like the C# (or C/C++/java) versions of the conditional operator, porting code would be even more challenging than it currently is since only one of those functions would be called.

Very similar concepts but implemented very differently!

2 Comments

  • I actually ran into a production bug where it was code with iif and nothing and it failed. Thanks

  • Thank you for the insight into this annoying little feature.

    I ran into the problem dealing with Date Types that don't allow you to specify whether or not they should throw an exception on NULL.

    I spent the whole time trying to figure out why I got a Cast Type Exception only to find out that both parts of the IIF were being evaluated!

Comments have been disabled for this content.