Недавно я узнал о функции IIF (A, B, C). Я долгое время работал кодировщиком VB / VB.NET, который недавно потратил много времени на то, чтобы научиться кодировать SQL.

Одна (очевидная) распространенная вещь в SQL - это что-то вроде следующего:

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

IIF (A, B, C) позволит мне сделать это в VB.NET ... все в одной строке.

Однако я читал, что и B, и C оцениваются независимо от того, что оценивает A.

Я могу вспомнить некоторые очевидные ситуации, когда это плохо, например:

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

Поскольку я буду включать это в свой репертуар, есть ли еще тонкие ситуации, когда я могу столкнуться с проблемами при использовании IIF?

В некоторых ситуациях это довольно большой отход от старомодного:

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

Я надеюсь избавиться от некоторых досадных проблем с производительностью и / или ошибок в будущем.

Обновление 2016

В последние несколько лет появилась новая функция VB.NET, которая устраняет необходимость использования функции IIF ().

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

Выполняются только ExecuteA () ИЛИ ExecuteB (). Наконец, встроенный IF с коротким замыканием.

Итак, если вы используете более поздние версии VB.NET (по состоянию на 2016 год), используйте это вместо этого, если можете.

58
Brian Webster 3 Авг 2009 в 05:50

5 ответов

Лучший ответ

Вот самая распространенная ошибка.

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

Не используйте его, чтобы избежать ошибок деления на ноль.

Другая возможная логическая ошибка - это когда одна сторона iif или другая вызывает метод, который изменяет состояние системы или имеет выходные параметры.

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

По моему опыту, на самом деле нет веских причин для использования IIF. В основном он просто используется для сокращения кода, и, учитывая проблемы, которые он может вызвать, оно того не стоит. Кроме того, я думаю, что это затрудняет чтение кода.

Еще одна неприятная вещь - это то, что он возвращает упакованное значение (т. Е. Тип данных Object), которое вы должны вернуть к желаемому типу.

41
JohnFx 5 Авг 2009 в 14:45

[IIF, а не IFF]

Наиболее частый случай, который мы видели, - это то, что одна или другая сторона оценивает как Nothing.

Ваш код может ожидать использования IIF в качестве защиты от получения NullReferenceException, например:

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

Но это не сработает, потому что всегда оцениваются обе стороны. Это случается часто в коде, написанном людьми, имеющими опыт работы на C / C ++ / C # / Java, поскольку в этих языках тернарный оператор ?: выполняет оценку короткого замыкания.

И тот факт, что документация VS 2005 IIF () утверждает, что IIF точно так же, как ?: не помогает:

Функция IIf представляет собой аналог тернарного условного оператора:? : в Visual C ++.

Нигде на этой справочной странице не говорится, что оцениваются обе стороны.

39
lavinio 3 Авг 2009 в 02:22

Что ж, вы также должны убедиться, что у вас нет в iif функций, которые изменяют какие-либо данные на основе условия. В большинстве случаев мы используем If. Просто стоит помнить об этом о iif.

1
Cyril Gupta 3 Авг 2009 в 02:07

Я был вынужден использовать iif (для компактности кода), где у меня был фрагмент кода, который копировал значения из многих массивов в электронную таблицу, но «пустые» записи в массиве приводят к выходу кода из подпрограммы (а не сбоям) ), поэтому я заключил строку в iif, чтобы проверить, не содержит ли ячейка массива ничего - если это так, то передайте обратно "", в противном случае верните ячейку массива (преобразование в строку 1st). Как было сказано выше, еще одна причина не использовать iif.

Я все еще в трауре из-за отсутствия функции NZ, которую я все время использовал в MS Access.

0
Kristian 17 Июн 2015 в 08:25