VB.NET – IIF (,,) – Les deux côtés sont évalués. Quelles situations dois-je surveiller?

J’ai récemment appris la fonction IIF (A, B, C). Je suis un codeur VB / VB.NET de longue date qui a récemment passé beaucoup de temps à accélérer le codage SQL.

Une chose commune (évidente) à faire en SQL est quelque chose comme:

select (case where @var = 0 then MyTable.Val1 else MyTable.Val2 end) from MyTable 

IIF (A, B, C) me permettra de le faire dans VB.NET … sur une seule ligne.

Cependant, j’ai lu que B et C sont évalués quel que soit le résultat de l’évaluation.

Je peux penser à certaines situations évidentes où c’est une mauvaise chose comme:

 Dim X as integer = IIF(SomeBoolean = true, ExpensiveFunction1(), ExpensiveFunction2()) 

Comme je vais l’inclure dans mon répertoire, y a-t-il d’autres situations plus subtiles où je pourrais avoir des problèmes avec l’utilisation de l’IIF?

C’est un très gros départ dans certaines situations d’utiliser l’ancien:

 Dim X as integer if SomeBoolean = true then X = ExpensiveFunction1() else X = ExpensiveFunction2() end if 

J’espère me sauver des problèmes de performance et / ou des bugs ennuyeux à l’avenir.

Mise à jour 2016

Ces dernières années, il existe une nouvelle fonctionnalité VB.NET qui élimine le besoin d’utiliser la fonction IIF ().

 if(Something = true, ExecuteA(), ExecuteB()) 

Seuls ExecuteA () OU ExecuteB () sont exécutés. Enfin, en ligne IF avec court-circuit.

Donc, si vous utilisez des versions ultérieures de VB.NET (à partir de 2016), utilisez-le plutôt si vous le pouvez.

Voici le truc le plus courant.

 Z = iif(y=0, 0, x/y) 'Throws a divide by zero exception when y is 0 

Ne l’utilisez pas pour éviter la division par des erreurs nulles.

Un autre bogue logique possible est celui où un côté de l’iif ou de l’autre appelle une méthode qui modifie l’état du système ou qui possède des parameters de sortie.

 Z = iif(FunctionA(InputOutputParam), FunctionB(InputOutputParam)) 'InputOutputParam is indeterminate or at least ambiguous here. 

Il n’y a vraiment aucune bonne raison d’utiliser IIF dans mon expérience. La plupart du temps, il est simplement utilisé pour abréger le code et compte tenu des problèmes qu’il peut causer, il ne vaut tout simplement pas la peine. De plus, je pense que cela rend le code plus difficile à lire.

L’autre chose qui mord est qu’il renvoie une valeur encadrée (c.-à-d. Un type de données object) que vous devez repasser au type souhaité.

[ IIF , pas IFF ]

Le cas le plus courant que nous avons vu est que l’un ou l’autre des deux côtés est évalué à Nothing .

Votre code peut s’attendre à utiliser IIF comme garde pour ne pas avoir une NullReferenceException , comme ceci:

 IIF(something Is Nothing, "nothing", something.Value) 

Mais cela ne fonctionnera pas, car les deux côtés sont toujours évalués. Cela se produit beaucoup dans le code écrit par des personnes qui viennent d’un arrière-plan C / C ++ / C # / Java, puisque dans ces langages l’opérateur ternaire ?: Évalue les courts-circuits.

Et le fait que la documentation de VS 2005 IIF () indique que IIF est juste comme:

La fonction IIf fournit une contrepartie à l’opérateur conditionnel ternaire: : dans Visual C ++.

Nulle part sur cette page de référence, il n’est indiqué que les deux côtés sont évalués.

Selon MSDN, l’opérateur «If» introduit dans VB2008 court-circuite à la place, ce qui serait idéal pour votre cas de calcul coûteux:

http://msdn.microsoft.com/en-us/library/bb513985.aspx

Eh bien, vous devez également vous assurer que vous n’avez aucune fonction dans iif qui modifie les données en fonction de la condition. Nous utilisons If pour beaucoup de cela. Il suffit de se souvenir de cela pour iif.

J’ai été obligé d’utiliser un iif (pour la compacité du code) où j’avais un morceau de code qui copiait des valeurs de nombreux tableaux dans une feuille de calcul, mais “rien” entrées dans le tableau fait que le code quitte le sous-programme ), j’ai donc placé la ligne dans un iif pour vérifier si la cellule du tableau ne contenait rien – si c’était le cas, puis repasser “” sinon, renvoyer la cellule du tableau (conversion en chaîne 1). Donc, comme dit ci-dessus, une autre raison de ne pas utiliser iif.

Je suis toujours en deuil en raison de l’absence de la fonction NZ que j’ai utilisée tout le temps dans MS Access.