Эквивалент Iif в C #


79

Есть ли IIfэквивалент в C #? Или аналогичный ярлык?


4
Я думаю, вы имели в виду «короткий путь», а не «короткое замыкание» (что имеет особое значение в отношении логических операторов) - я прав?
Blorgbeard выйдет

Ответы:


120

В C # ?, как и в других языках C-стиля, есть тернарный оператор. Однако это не полностью эквивалентно IIf(); есть два важных отличия.

Чтобы объяснить первое отличие, аргумент ложной части для этого IIf()вызова вызывает a DivideByZeroException, хотя логический аргумент имеет значение True.

IIf(true, 1, 1/0)

IIf()- это просто функция, и, как и все функции, все аргументы должны быть оценены перед вызовом. Иными словами, IIf()делает не короткое замыкание в традиционном смысле этого слова. С другой стороны, в этом троичном выражении происходит короткое замыкание, и поэтому все в порядке:

(true)?1:1/0;

Другое отличие IIf()- небезопасный тип. Он принимает и возвращает аргументы типа Object. Тройной оператор является тип безопасности. Он использует вывод типов, чтобы знать, с какими типами имеет дело. Обратите внимание, что вы можете очень легко исправить это с помощью своей собственной общей IIF(Of T)()реализации, но из коробки это не так.

Если вы действительно хотите использовать IIf()C #, вы можете получить его:

object IIf(bool expression, object truePart, object falsePart) 
{return expression?truePart:falsePart;}

или универсальная / типобезопасная реализация:

T IIf<T>(bool expression, T truePart, T falsePart) 
{return expression?truePart:falsePart;}

С другой стороны, если вы хотите, чтобы тернарный оператор в VB, Visual Studio 2008 и более поздних версий предоставил новый If() оператор, который работает как тернарный оператор C #. Он использует вывод типа, чтобы узнать, что он возвращает, и на самом деле это оператор, а не функция. Это означает, что нет проблем с предварительной оценкой выражений, даже если они имеют семантику функций.


2
VB9 поддерживает истинный тернарный оператор. Если (SomeBool, MessageBox.Show ("True"), MessageBox.Show ("False")) Как видно здесь: community.bartdesmet.net/blogs/bart/archive/2007/08/31/…
snarf

1
Я упоминал об этом в последнем абзаце, но вопрос касался именно IIf ().
Джоэл Кохорн

61

VB.NET:

If(someBool, "true", "false")

C #

someBool ? "true" : "false";

1
Хотя это верно для простых выражений, эти две формы не совсем эквивалентны, если в альтернативных выражениях есть побочные эффекты. Iif (t, foo (), bar ()) будет вызывать как foo (), так и bar (), а t? foo (): bar () будет вызывать только либо foo (), либо bar (), но не оба сразу. См. Ответ Джоэла Кохорна на этот вопрос для получения дополнительной информации.
Грег Хьюгилл

1
Обновлен ответ на использование функции «If» VB.NET вместо «IIf», чтобы два блока кода были эквивалентны.
Кевин Пан,

13

тернарный оператор

bool a = true;

string b = a ? "if_true" : "if_false";

я бы добавил туда комментарий, что строка b = (a? "asdf": "dsrs"); т.е. тогда можно лучше понять, как это работает, и увидеть, что это не что-то действительно странное и бессмысленное, например (строка b = a)? "sdf": "sdsdf").
barlop

10

Также полезен оператор объединения ??:

VB:

Return Iif( s IsNot Nothing, s, "My Default Value" )

C #:

return s ?? "My Default Value";



0

Он ограничен тем, что вы не можете помещать туда заявления. Вы можете только помещать значения (или вещи, которые возвращают / оценивают значения), чтобы вернуть

Это работает ('a' - статический int в классе Blah)

Blah.a=Blah.a<5?1:8;

(круглые скобки явно ставятся между знаком равенства и вопросительным знаком).

Это не работает.

Blah.a = Blah.a < 4 ? Console.WriteLine("asdf") : Console.WriteLine("34er");
or
Blah.a = Blah.a < 4 ? MessageBox.Show("asdf") : MessageBox.Show("34er");

Таким образом, вы можете использовать только тернарный оператор C # для возврата значений. Так что это не совсем похоже на сокращенную форму if. Javascript и, возможно, некоторые другие языки позволяют помещать туда операторы.


Да, потому что он устанавливает значение, а не вызывает метод. Однако вы можете Actionделать то, что хотите.
Kieran Foot

@KieranFoot WriteLine - это метод. Прошло некоторое время, но If iifили тернарный оператор, позвольте вам поместить туда возвращаемое значение, например, Blah.a = Blah.a < 4 ? Console.WriteLine("asdf"); return 1: Console.WriteLine("34er") ; return 2; если бы он это позволял, это сработало бы, но, по-видимому, это не так. И да, он все еще устанавливает значение и не вызывает там никаких новых методов.
barlop
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.