?: ?? Operatoren anstelle von IF | ELSE


85
public string Source
{
    get
    {
        /*
        if ( Source == null ){
            return string . Empty;
        } else {
            return Source;
        }
        */
        return Source ?? string.Empty;
    }
    set
    {
        /*
        if ( Source == null ) {
            Source = string . Empty;
        } else {
            if ( Source == value ) {
                Source = Source;
            } else {
                Source = value;
            }
        }
        */
        Source == value ? Source : value ?? string.Empty;
        RaisePropertyChanged ( "Source" );
    }
}

Kann ich ?: ??Operatoren GENAU als If / Else verwenden?


Meine Frage:
Wie schreibe ich folgendes mit ?: ?? Betreiber

[1]

if ( Source == null ){
    // Return Nothing
} else {
    return Source;
}

[2]

if ( Source == value ){
    // Do Nothing
} else {
    Source = value;
    RaisePropertyChanged ( "Source" );
} 

Kurz gesagt : Wie kann man nichts tun, nichts zurückgeben und mehrere Anweisungen mit dem ?: ??Bediener ausführen?


1
Es wird sich jedoch nicht gleich verhalten. Wenn Sie keine bedingte if / else-Verzweigung verwenden, weisen Sie die Variable bei jedem Zugriff bedingungslos (und unnötig) neu zu. Das kann sehr schnell schlecht werden, besonders wenn Sie Multithread-Code haben. Tu es einfach nicht.
Jeff Mercado

1
Sie erhalten einen endlosen / rekursiven Aufruf, wenn der get-Accessor der Source-Eigenschaft die Source-Eigenschaft (ihren get-Accessor) zurückgibt.
John K

1
Ihr erstes Code-Snippet verfügt über einen Eigenschafts-Getter, der seinen eigenen Setter aufruft , der seinerseits rekursiv seinen eigenen Getter aufruft . Du hast mich dort verloren, da so etwas auf dem Feld unmöglich funktionieren würde. Bitte verfeinern Sie Ihre Frage und erklären Sie genau, was Sie erreichen möchten.
Frédéric Hamidi

Nichts zurückgeben? Das ist VB. Du schreibst hier c #.
Aufgabe

@ Aufgabe Ich meine, wie das geht, diese Zeile ist ein Kommentar für die Frage
Ahmed Ghoneim

Antworten:


198

Für [1] können Sie nicht: Diese Operatoren geben einen Wert zurück und führen keine Operationen aus.

Der Ausdruck

a ? b : c

wertet aus, bob awahr ist, und bewertet, cob afalsch ist.

Der Ausdruck

b ?? c

wertet aus, bwenn bnicht null ist, und wertet aus, cwenn bes null ist.

Wenn du schreibst

return a ? b : c;

oder

return b ?? c;

Sie werden immer etwas zurückgeben.

Für [2] können Sie eine Funktion schreiben, die den richtigen Wert zurückgibt, der Ihre "Mehrfachoperationen" ausführt, aber das ist wahrscheinlich schlimmer als nur die Verwendung if/else.


41

Der ternäre Operator ( ?:) ist nicht für den Kontrollfluss ausgelegt , sondern nur für die bedingte Zuweisung . Wenn Sie den Ablauf Ihres Programms steuern müssen, verwenden Sie eine Steuerungsstruktur wie if/ else.


5
Ich werde hinzufügen, dass ich gesehen habe, dass Leute verschachtelte ternäre Ausdrücke anstelle von if / else verwenden, und dass Code erzeugt wird, der schwer zu lesen und zu debuggen ist. Überall schlechtes Mojo.
ckramer

4
Manchmal erzeugen verschachtelte ternäre Operatoren besser lesbaren Code, wenn Leerzeichen richtig verwendet werden.
Wahrhaftigkeit

2
@ Wahrheit: Ja, ich habe nichts gegen verschachtelt ?:per se. Aber ich habe ein großes Problem damit, dass sie für den Kontrollfluss und insbesondere für den verschachtelten Kontrollfluss verwendet werden!
Oliver Charlesworth

11

Bezugnehmend auf ?: Operator (C # -Referenz)

Der bedingte Operator (? :) Gibt abhängig vom Wert eines Booleschen Ausdrucks einen von zwei Werten zurück. Es folgt die Syntax für den bedingten Operator.

Bezugnehmend auf ?? Operator (C # -Referenz)

Das ?? Der Operator wird als Null-Koaleszenz-Operator bezeichnet und wird verwendet, um einen Standardwert für einen nullbaren Werttyp sowie Referenztypen zu definieren. Es gibt den linken Operanden zurück, wenn er nicht null ist. Andernfalls wird der richtige Operand zurückgegeben.

Das bedeutet:

[Teil 1]

return source ?? String.Empty;

[Teil 2] ist nicht anwendbar ...


3
Das ist anders als nichts zu tun. Es wird eine leere Zeichenfolge zurückgegeben.
Wahrhaftigkeit

1
Sicher, aber das hat das OP nicht verlangt. Es ist nicht meine Schuld, dass das OP darum gebeten hat, "nichts zurückzugeben" - was auch immer das möglicherweise bedeuten kann.
Wahrhaftigkeit

1
@ Wahrheit: Kein Körper sagte, es sei deine Schuld. Allerdings wollte das OP nichts zurückgeben und das, was ich zur Verfügung gestellt habe.
Akram Shahda

3

Das "nichts tun" funktioniert nicht wirklich für?

Wenn mit // Return Nothing gemeint ist, dass return null ist, dann schreibe

return Source;

Wenn Sie meinen, ignorieren Sie den Codepfad und schreiben Sie

 if ( Source != null )
            {
                return Source;
            }
// source is null so continue on.

Und zum letzten

 if ( Source != value )
            { Source = value;
                RaisePropertyChanged ( "Source" );
            }

// nothing done.

3

Der ternäre Operator gibt einen von zwei Werten zurück. Oder es kann eine von zwei Anweisungen basierend auf seinem Zustand ausführen, aber das ist im Allgemeinen keine gute Idee, da es zu unbeabsichtigten Nebenwirkungen führen kann.

bar ? () : baz();

In diesem Fall macht das () nichts, während baz etwas macht. Aber Sie haben den Code nur weniger klar gemacht. Ich würde mich für ausführlicheren Code entscheiden, der klarer und einfacher zu warten ist.

Darüber hinaus macht dies überhaupt wenig Sinn:

var foo = bar ? () : baz();

da () keinen Rückgabetyp hat (es ist ungültig) und baz einen Rückgabetyp hat, der zum Zeitpunkt des Aufrufs in diesem Beispiel unbekannt ist. Wenn sie nicht einverstanden sind, wird sich der Compiler lautstark beschweren.


2

Wenn Sie sich mit der Ausführlichkeit Ihres Codes befassen, würde ich dies schreiben, anstatt zu versuchen, Ausdrücke zu missbrauchen.

if (Source == value) return;
Source = value;
RaisePropertyChanged("Source");

Ich missbrauche keine Ausdrücke, ich denke nur!
Ahmed Ghoneim

1

das?: ist der Reiseroutenbetreiber. (glaube, ich habe das richtig geschrieben) und es ist einfach zu bedienen. wie in einem booleschen Prädikat? iftrue: ifalse; Aber Sie müssen einen rWert / lWert wie in rWert = Prädikat haben? iftrue: iffalse;

Ex int i = x < 7 ? x : 7;

Wenn x kleiner als 7 wäre, würde mir x zugewiesen werden, wenn nicht, wäre ich 7.

Sie können es auch in einer Rückgabe verwenden, wie in return x < 7 ? x : 7;

wie oben hätte dies wiederum den gleichen Effekt.

so, Source = Source == value ? Source : string.Empty;glaube ich , ist das, was Ihr zu acheive versuchen.


6
Ich mag das. Der Reiseroutenbetreiber : Er hilft Ihnen, von A nach B zu gelangen ... oder von A nach C ... je nach A.
Rick Sladkey

Ja, er meint ternär. Der korrekte Name lautet jedoch "bedingt".
Erick G. Hagstrom


0

Ich glaube nicht, dass Sie ein Operator sein können und davon ausgehen, dass Sie den einen oder anderen zurückgeben. Es ist nicht, wenn sonst die Anweisung ersetzt wird, obwohl sie in bestimmten Fällen dafür verwendet werden kann.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.