Подтвердить что ты не робот

VB.NET - IIF (,) - оцениваются обе "стороны". В каких ситуациях я должен следить?

Недавно я узнал о функции IIF (A, B, C). Я долгое время VB/VB.NET Coder, который недавно потратил много времени на ускорение в 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 года), используйте это, если можете.

4b9b3361

Ответ 1

Вот наиболее распространенный вопрос.

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. В основном это просто используется для сокращения кода и с учетом проблем, которые он может вызвать, но это просто не стоит. Плюс, я думаю, что это делает код более трудным для чтения.

Другая вещь, которая кусается, заключается в том, что она возвращает значение в виде бокса (то есть тип данных объекта), которое вы должны вернуть назад к нужному типу.

Ответ 2

[IIF, not IFF]

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

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

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

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

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

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

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

Ответ 3

Согласно MSDN, оператор "If", введенный в VB2008, будет иметь короткое замыкание, что было бы идеальным для вашего дорогостоящего случая вычислений:

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

Ответ 4

Ну, вы также должны убедиться, что в iif нет никаких функций, которые изменяют любые данные на основе условия. Мы используем If для этого довольно много. Это просто платит, чтобы вспомнить об iif.

Ответ 5

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

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