Iif equivalente en C #

79

¿Existe un IIfequivalente en C #? ¿O un atajo similar?

Saif Khan
fuente
4
Creo que quisiste decir "atajo", en lugar de "cortocircuito" (que tiene un significado específico con respecto a los operadores booleanos), ¿verdad?
Blorgbeard sale

Respuestas:

120

C # tiene el ?operador ternario, como otros lenguajes de estilo C. Sin embargo, esto no es perfectamente equivalente a IIf(); hay dos diferencias importantes.

Para explicar la primera diferencia, el argumento de la parte falsa para esta IIf()llamada causa a DivideByZeroException, aunque el argumento booleano es True.

IIf(true, 1, 1/0)

IIf()es solo una función y, como todas las funciones, todos los argumentos deben evaluarse antes de realizar la llamada. Dicho de otra manera, IIf()lo hace no cortocircuito en el sentido tradicional. Por otro lado, esta expresión ternaria hace un cortocircuito, por lo que está perfectamente bien:

(true)?1:1/0;

La otra diferencia es IIf()que no es seguro de tipos. Acepta y devuelve argumentos de tipo Object. El operador ternario es de tipo seguro. Utiliza la inferencia de tipos para saber con qué tipos está tratando. Tenga en cuenta que puede solucionar este problema muy fácilmente con su propio genéricoIIF(Of T)() implementación , pero no es así de inmediato.

Si realmente lo desea IIf()en C #, puede tenerlo:

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

o una implementación genérica / segura de tipos:

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

Por otro lado, si desea el operador ternario en VB, Visual Studio 2008 y versiones posteriores proporcionan un nuevo If() operador que funciona como el operador ternario de C #. Utiliza la inferencia de tipos para saber lo que está devolviendo, y realmente es un operador en lugar de una función. Esto significa que no hay problemas con la evaluación previa de expresiones, aunque tiene semántica de funciones.

Joel Coehoorn
fuente
2
VB9 admite un verdadero operador ternario. If (SomeBool, MessageBox.Show ("True"), MessageBox.Show ("False")) Como se ve aquí: community.bartdesmet.net/blogs/bart/archive/2007/08/31/…
snarf
1
Lo menciono en el último párrafo, pero la pregunta era específicamente sobre IIf ().
Joel Coehoorn
61

VB.NET:

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

C#

someBool ? "true" : "false";
Kevin Pang
fuente
1
Si bien esto es cierto para las expresiones simples, las dos formas no son exactamente equivalentes si hay efectos secundarios en las expresiones alternativas. Si (t, foo (), bar ()) llamará tanto a foo () como a bar (), mientras que t? foo (): bar () solo llamará a foo () o bar () pero no a ambos. Consulte la respuesta de Joel Coehoorn a esta pregunta para obtener más información.
Greg Hewgill
1
Respuesta actualizada para usar la función "If" de VB.NET en lugar de "IIf" para que los dos bloques de código sean equivalentes.
Kevin Pang
13

el operador ternario

bool a = true;

string b = a ? "if_true" : "if_false";
Ris Adams
fuente
agregaría un comentario que esa es la cadena b = (a? "asdf": "dsrs"); es decir, entonces es posible comprender mejor cómo funciona la cosa y ver que no es algo realmente extraño y sin sentido como (cadena b = a). "sdf": "sdsdf").
barlop
10

También es útil el operador de fusión ??:

VB:

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

C#:

return s ?? "My Default Value";
John Gibb
fuente
1

Es el operador ternario ?

string newString = i == 1 ? "i is one" : "i is not one";
Jon Limjap
fuente
0

Está limitado en el sentido de que no puede poner declaraciones allí. Solo puede poner valores (o cosas que devuelven / evalúan a valores), para devolver

Esto funciona ('a' es un int estático dentro de la clase Blah)

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

(los corchetes están implícitamente entre los iguales y el signo de interrogación).

Esto no funciona.

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

Por lo tanto, solo puede usar el operador ternario c # para devolver valores. Así que no es como una forma abreviada de un if. Javascript y quizás algunos otros lenguajes le permiten poner declaraciones allí.

barlop
fuente
Sí, porque establece un valor, no invoca un método. Sin embargo, podrías usar Actionpara hacer lo que quieras.
Kieran Foot
@KieranFoot WriteLine es un método. Ha pasado un tiempo, pero si iifo el operador ternario, le permiten poner un valor de retorno allí como Blah.a = Blah.a < 4 ? Console.WriteLine("asdf"); return 1: Console.WriteLine("34er") ; return 2; si lo permitiera, funcionaría, pero aparentemente no es así. Y sí, todavía está estableciendo un valor, y no, no está llamando a ningún método nuevo allí.
Barlop