IIf function evaluates both of its result arguments

ID

vbnet.performance.avoid_iif

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Performance

Language

VB.NET

Description

Reports calls to the legacy IIf function, which selects between two values at run time. Unlike the If operator it is an ordinary function call, so the arguments for both the true part and the false part are evaluated before the selection is made.

Rationale

Because both result arguments are always evaluated, IIf pays for work it then discards, and the condition does not protect the branch it appears to guard: IIf(count > 0, total / count, 0) still performs the division when count is zero, and IIf(o Is Nothing, "", o.Name) still dereferences o and throws a NullReferenceException. The parameters and the result are typed Object, so every value type is boxed - an extra allocation per call - and no compile-time type checking is applied to either branch.

The following code illustrates the pattern detected by this rule:

Public Function DiscountRate(ByVal isPremium As Boolean) As Double
    ' FLAGGED: IIf function evaluates both of its result arguments
    Return CDbl(IIf(isPremium, 0.15, 0.0))
End Function

Remediation

Use the If operator, which short-circuits and evaluates only the branch it returns, keeps the static type of the operands, and does not box. For longer branches use a plain If …​ Then …​ Else statement.

' Before: the division runs even when count is 0
Return CDbl(IIf(count > 0, total / count, 0.0))

' After: only the selected branch is evaluated
Return If(count > 0, total / count, 0.0)

Configuration

This detector does not need any configuration.