VB.Net Tip: IIF is a function, not a language feature

I think i've found a nice way to demonstrate this age old gotcha in VB.

What result do you expect from this line of VB code?

IIf(True, MsgBox("hello"), MsgBox("goodbye"))

(continues...)

Do you expect only the first message box to show up?

You might think it would just execute the:

MsgBox("hello")

But you'd be as wrong as a fez with a brim.

BOTH message boxes will come up, one after the other. Try it and see.

Is this a bug? Is this insane? Is this dangerous?

No, no and yes occasionally. The thing is that IIF is just a built in function. And when you try to send expressions to it, they get evaluated before the function sees them. The same happens any time you send expressions to any function.

So it's not a bug, and it's also unlikely to change in any version of VB, or any future version of the IIF function. So it's worth taking the time to remember it, understand it and work with it.

Now when is this likely to pose a problem?

To avoid a divide-by-zero error, many a coder has tried this:

IIf(divisor=0, c, a / divisor)

And they will of course still get a "Divide By Zero" error, if the divisor equals zero.

Again, that's because IIF is just a function. And like all functions in vb, it doesn't accept expressions as parameters. So the expressions must be evaluated before they are passed to the IIF function. Hence the error.

The longer syntax, using full if statements, will work as desired:

        If divisor = 0 Then

            Return c

        Else

            Return a / divisor

        End If

And that's pretty much the best way to skin this little kitten.

(thanks to derek for reminding me to post about this)


One little footnote, is that in Excel, if you type:

        IF (TRUE,TRUE, 5/0)

...you won't get an error message -- because some sort of shortcutting is happening, and the false code path isn't executed.

So, to get a "#DIV/0!" error message, you'd need to get that particular trouser leg of the if statement to fire, like so:

        IF (FALSE,TRUE, 5/0)

 

Your comment, please?

Your Name
Your Url (optional)
Note: I may edit, reuse or delete your comment. Don't be mean.