Wenn äquivalent in C #

79

Gibt es ein IIfÄquivalent in C #? Oder eine ähnliche Verknüpfung?

Saif Khan
quelle
4
Ich denke, Sie meinten "Abkürzung" und nicht "Kurzschluss" (was eine spezifische Bedeutung in Bezug auf Boolesche Operatoren hat) - habe ich Recht?
Blorgbeard ist

Antworten:

119

C # hat den ?ternären Operator, wie andere Sprachen im C-Stil. Dies ist jedoch nicht perfekt gleichbedeutend mit IIf(); Es gibt zwei wichtige Unterschiede.

Um den ersten Unterschied zu erklären, verursacht das Argument false-part für diesen IIf()Aufruf a DivideByZeroException, obwohl das boolesche Argument lautet True.

IIf(true, 1, 1/0)

IIf()ist nur eine Funktion, und wie bei allen Funktionen müssen alle Argumente ausgewertet werden, bevor der Aufruf erfolgt. Anders ausgedrückt, IIf()schließt nicht im herkömmlichen Sinne kurz. Auf der anderen Seite schließt dieser ternäre Ausdruck kurz und ist daher vollkommen in Ordnung:

(true)?1:1/0;

Der andere Unterschied IIf()ist nicht typsicher. Es akzeptiert Argumente vom Typ und gibt sie zurück Object. Der ternäre Operator ist typsicher. Mithilfe der Typinferenz wird ermittelt, um welche Typen es sich handelt. Beachten Sie, dass Sie dies sehr einfach mit Ihrer eigenen generischen IIF(Of T)()Implementierung beheben können , aber sofort ist das nicht so.

Wenn Sie wirklich IIf()in C # wollen, können Sie es haben:

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

oder eine generische / typsichere Implementierung:

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

Wenn Sie andererseits den ternären Operator in VB verwenden möchten, stellen Visual Studio 2008 und höher einen neuen If() Operator bereit , der wie der ternäre Operator von C # funktioniert. Es verwendet Typinferenz, um zu wissen, was es zurückgibt, und es ist wirklich eher ein Operator als eine Funktion. Dies bedeutet, dass es keine Probleme bei der Vorbewertung von Ausdrücken gibt, obwohl diese über eine Funktionssemantik verfügen.

Joel Coehoorn
quelle
2
VB9 unterstützt einen echten ternären Operator. If (SomeBool, MessageBox.Show ("True"), MessageBox.Show ("False")) Wie hier zu sehen: community.bartdesmet.net/blogs/bart/archive/2007/08/31/…
snarf
1
Ich erwähne es im letzten Absatz, aber die Frage betraf speziell IIf ().
Joel Coehoorn
61

VB.NET:

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

C #

someBool ? "true" : "false";
Kevin Pang
quelle
1
Während dies für einfache Ausdrücke gilt, sind die beiden Formen nicht genau gleichwertig, wenn die alternativen Ausdrücke Nebenwirkungen aufweisen. Iif (t, foo (), bar ()) ruft sowohl foo () als auch bar () auf, während t? foo (): bar () ruft nur entweder foo () oder bar () auf, aber nicht beide. Weitere Informationen finden Sie in Joel Coehoorns Antwort auf diese Frage.
Greg Hewgill
1
Die Antwort wurde aktualisiert, um die "If" -Funktion von VB.NET anstelle von "IIf" zu verwenden, sodass die beiden Codeblöcke gleichwertig sind.
Kevin Pang
13

der ternäre Operator

bool a = true;

string b = a ? "if_true" : "if_false";
Ris Adams
quelle
Ich würde dort einen Kommentar hinzufügen, dass das String b = (a? "asdf": "dsrs") ist. dh dann ist es möglich, besser zu verstehen, wie das Ding funktioniert, und zu sehen, dass es nicht wirklich seltsam und unsinnig ist (String b = a)? "sdf": "sdsdf").
Barlop
10

Ebenfalls nützlich ist der Koaleszenzoperator ??:

VB:

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

C #:

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

Es ist der ternäre Operator ?

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

Es ist insofern begrenzt, als Sie dort keine Aussagen einfügen können. Sie können nur Werte (oder Dinge, die Werte zurückgeben / auswerten), zurückgeben

Dies funktioniert ('a' ist ein statisches int innerhalb der Klasse Blah)

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

(runde Klammern stehen implizit zwischen dem Gleichheitszeichen und dem Fragezeichen).

Das funktioniert nicht.

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

Sie können also nur den ternären Operator c # verwenden, um Werte zurückzugeben. Es ist also nicht ganz wie eine verkürzte Form eines Wenn. Mit Javascript und vielleicht einigen anderen Sprachen können Sie dort Aussagen machen.

Barlop
quelle
Ja, da ein Wert festgelegt wird und keine Methode aufgerufen wird. Sie könnten Actionjedoch tun, was Sie wollen.
Kieran Foot
@KieranFoot WriteLine ist eine Methode. Es ist schon eine Weile her, aber wenn iifoder der ternäre Operator, lassen Sie einen Rückgabewert wie dort eingeben, Blah.a = Blah.a < 4 ? Console.WriteLine("asdf"); return 1: Console.WriteLine("34er") ; return 2; wenn es das erlaubt, würde es funktionieren, aber anscheinend nicht. Und ja, es setzt immer noch einen Wert und nein, es ruft dort keine neue Methode auf.
Barlop