VB.NET-IIF(,,)-Ambos "lados" son evaluados. ¿Con qué situaciones debo estar atento?
(5)
Aquí está el gotcha más común.
Z = iif(y=0, 0, x/y) ''Throws a divide by zero exception when y is 0
No lo use para evitar la división por cero errores.
Otro posible error lógico es cuando un lado del iif u otro llama a un método que modifica el estado del sistema o tiene parámetros de salida.
Z = iif(FunctionA(InputOutputParam), FunctionB(InputOutputParam))
''InputOutputParam is indeterminate or at least ambiguous here.
Realmente no hay una buena razón para usar IIF en mi experiencia. En su mayoría, se utiliza para abreviar el código y, dados los problemas que puede causar, simplemente no lo vale. Además, creo que hace que el código sea más difícil de leer.
La otra cosa que muerde es que devuelve un valor en caja (es decir, un tipo de datos de Objeto) que debe devolver al tipo deseado.
Recientemente me enteré de la función IIF (A, B, C). Hace tiempo que soy codificador de VB / VB.NET y recientemente pasé mucho tiempo acelerando la codificación de SQL.
Una cosa (obvia) común en SQL es algo como lo siguiente:
select (case where @var = 0 then MyTable.Val1 else MyTable.Val2 end) from MyTable
IIF (A, B, C) me permitirá hacer esto en VB.NET ... todo en una línea.
Sin embargo, he leído que tanto B como C se evalúan sin importar lo que A evalúe.
Puedo pensar en algunas situaciones obvias donde esto es algo malo como:
Dim X as integer = IIF(SomeBoolean = true, ExpensiveFunction1(), ExpensiveFunction2())
Como incluiré esto en mi repertorio, ¿hay situaciones más sutiles en las que pueda tener problemas para usar IIF?
En algunas situaciones, es una gran desviación del uso de lo anticuado:
Dim X as integer
if SomeBoolean = true then
X = ExpensiveFunction1()
else
X = ExpensiveFunction2()
end if
Espero ahorrarme algunos molestos problemas de rendimiento y / o errores en el futuro.
Actualización 2016
En los últimos años, existe una nueva característica de VB.NET que elimina la necesidad de utilizar la función IIF ().
if(Something = true, ExecuteA(), ExecuteB())
Solo se ejecutan ExecuteA () O ExecuteB (). Finalmente, IF en línea con cortocircuito.
Por lo tanto, si está utilizando versiones posteriores de VB.NET (a partir de 2016), use esto en su lugar si puede.
Bueno, también debes asegurarte de que no tienes ninguna función en iif que modifique cualquier dato basado en la condición. Usamos Si por una gran cantidad de eso. Vale la pena recordar eso sobre iif.
Me vi obligado a utilizar un iif (por compacidad de código) donde tenía un trozo de código que copiaba valores de muchas matrices en una hoja de cálculo, pero las entradas "nada" en la matriz hacen que el código salga de la subrutina (no se bloquea ), así que envolví la línea en un iif para verificar si la celda de la matriz no contenía nada; si lo hizo, entonces vuelva a pasar "", de lo contrario, devuelva la celda de la matriz (convirtiéndola en una cadena 1ra). Como se dijo anteriormente, otra razón para no usar iif.
Todavía estoy de luto debido a la falta de la función NZ que utilicé todo el tiempo en MS Access.
Según MSDN, el operador "If" introducido en VB2008 provocará un cortocircuito, lo que sería ideal para su costoso caso de computación:
[ IIF
, no IFF
]
El caso más común que hemos visto es que uno u otro lado se evalúa como Nothing
.
Su código podría estar esperando usar IIF
como guardia para evitar obtener una NullReferenceException
, como esta:
IIF(something Is Nothing, "nothing", something.Value)
Pero eso no funcionará, porque ambos lados siempre son evaluados. Esto sucede mucho en el código escrito por personas que provienen de un fondo C / C ++ / C # / Java, ya que en esos idiomas el operador ternario ?:
Realiza una evaluación de cortocircuito.
¿Y el hecho de que la documentación de VS 2005 IIF () dice que IIF
es exactamente igual a ?:
No ayuda:
La función IIf proporciona una contraparte para el operador condicional ternario:? : en Visual C ++.
En ninguna parte de esa página de referencia dice que se evalúan ambos lados.