Stop using IIF by ThinqLinq

Stop using IIF

For a long time, VB has had an operator called IIF which allows you to evaluate a condition and return a true value or false value as a single line evaulation. I'm sure some of you out there have used the IIF function at some point in the past. If you're unsure, here's a quick sample piece of code.

    Console.WriteLine(IIf(x > 1, Evaluate(True), Evaluate(False)))

In this case, we evaulate the expression x > 1. If it is true, we call a method called Evaluate passing true and return that result. Here's the definition of this function:

    Private Function Evaluate(ByVal value As Boolean) As Boolean
        Debug.WriteLine("Evaluating: " & value.ToString)
    End Function

If it is false, we call the Evaluate method passing false. This evaluate method simply outputs the value and returns it. I use the method to log the output. IIf has one big problem. It evaluates both sides of the expression regardless of the result of the condition. If we run the line above setting x to 2, we get the following output:

Evaluating: True
Evaluating: False
False

As you can see, even though our condition evaluates to false, we still run the Evalute function for the true case in addition to the false case. Other than the fact that we are un-necessarily burning excess cycles to run the method needlessly, there is a deeper downside for this version. Consider if we were to increment a module level variable in the Evalute method that variable would be incremented twice rather than once for this single function. It gets worse if other functions are done inside of the evaluation.

Finally with VB 9, we will get a true ternary If operator. With this new operator, only the true or false side of the evaluation will be processed. Rather than changing the implementation of the existing IIf operator, we have a new If(condition, truePart, falsePart). Why? Because the VB team didn't want to break existing applications which relied on having both sides always evaluated. To use the revised operator, we simply need to remove an "I" as follows:

     Debug.WriteLine(If(x > 1, Evaluate(True), Evaluate(False)))

Unlike the previous example, this version only evaluates the side which agrees with the condition. If the value of x is 2, the following output results:

If (ternary):Evaluating: True
False

The result is not limited to Boolean. Because of type inference, as long as both the True and False sides of the evaluation result in the same type, the compiler can infer the type and respond appropriately. You can even return a If delegate as the result of an If evaluation. Thus you can nest complex evaulations in a functional manner.

The VB team didn't stop there with If however. They also implemented a version for nullable types which take the condition and tries to evaluate it. If the result is Nothing, the false side of the expression is evaluted. Thus in the following example, if Y is nothing, the result will be False. If Y is 1, the result outputs as True.

Debug.WriteLine(If(y > 0, False))

As a result, If(You.Uses = VB9,"UseIf","AvoidIIf")

Posted on - Comment
Categories: VB -
comments powered by Disqus