?: ?? Operatori invece di 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" );
    }
}

Posso usare gli ?: ??operatori ESATTAMENTE come If / Else?


La mia domanda:
come scrivere quanto segue con?: ?? operatori

[1]

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

[2]

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

In breve : come non fare nulla, non restituire nulla e eseguire più istruzioni con l' ?: ??operatore?


1
Tuttavia, non si comporterà allo stesso modo. Non usando la ramificazione condizionale if / else, stai riassegnando incondizionatamente (e inutilmente) la variabile ogni volta che vi accedete. Ciò può andare male molto rapidamente, soprattutto se hai codice multi-thread. Basta non farlo.
Jeff Mercado

1
Avrai una chiamata infinita / ricorsiva se la funzione di accesso get della proprietà Source restituisce la proprietà Source (la sua funzione di accesso get).
John K

1
Il tuo primo frammento di codice ha una proprietà getter che chiama il proprio setter , che a sua volta chiama ricorsivamente il proprio getter . Mi hai perso lì, perché non è possibile che qualcosa del genere possa funzionare sul campo. Per favore, affina la tua domanda e spiega esattamente cosa vuoi ottenere.
Frédéric Hamidi

Non restituire niente? Questo è VB. Stai scrivendo c # qui.
Attività

@Task Intendo come farlo, questa riga è un commento per la domanda
Ahmed Ghoneim,

Risposte:


198

Per [1], non puoi: questi operatori sono fatti per restituire un valore, non per eseguire operazioni.

L'espressione

a ? b : c

restituisce bse aè vero e restituisce cse aè falso.

L'espressione

b ?? c

restituisce bif bnon è null e restituisce cif bè null.

Se scrivi

return a ? b : c;

o

return b ?? c;

essi saranno sempre restituire qualcosa.

Per [2], puoi scrivere una funzione che restituisce il valore corretto che esegue le tue "operazioni multiple", ma probabilmente è peggio del semplice utilizzo if/else.


41

L'operatore ternario ( ?:) non è progettato per il flusso di controllo , è progettato solo per l' assegnazione condizionale . Se hai bisogno di controllare il flusso del tuo programma, usa una struttura di controllo, come if/ else.


5
Aggiungerò che ho visto persone usare espressioni ternarie nidificate al posto di if / else e produce codice difficile da leggere e da eseguire il debug. Cattivo mojo tutto intorno.
ckramer

4
A volte gli operatori ternari annidati producono codice più leggibile, se gli spazi bianchi sono usati correttamente.
trutheality

2
@truth: Sì, non ho nulla contro annidato di ?:per sé. Ma ho un grosso problema con il loro utilizzo per il flusso di controllo, e soprattutto per il flusso di controllo annidato !
Oliver Charlesworth

11

Riferimento a ?: Operatore (riferimenti per C #)

L'operatore condizionale (? :) restituisce uno dei due valori a seconda del valore di un'espressione booleana. Di seguito è riportata la sintassi per l'operatore condizionale.

Riferendosi a ?? Operatore (riferimenti per C #)

Il ?? L'operatore viene chiamato operatore di coalescenza null e viene utilizzato per definire un valore predefinito per i tipi di valore nullable e per i tipi di riferimento. Restituisce l'operando di sinistra se non è nullo; altrimenti restituisce l'operando di destra.

Questo significa:

[Parte 1]

return source ?? String.Empty;

[Parte 2] non è applicabile ...


3
È diverso dal non fare nulla. Restituisce una stringa vuota.
trutheality

1
Certo, ma non è quello che chiedeva l'OP. Non è colpa mia se il PO ha chiesto di "non ritorno" - qualunque cosa che può significare.
trutheality

1
@trutheality: Nessun corpo ha detto che è colpa tua .. Tuttavia, l'OP non voleva restituire nulla e questo è quello che ho fornito.
Akram Shahda

3

Il "non fare niente" non funziona davvero?

se per // Return Nothing intendi effettivamente restituire null allora scrivi

return Source;

se intendi, ignora il codepath e poi scrivi

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

E per ultimo

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

// nothing done.

3

L'operatore ternario RESTITUISCE uno di due valori. Oppure può eseguire una delle due istruzioni in base alle sue condizioni, ma in genere non è una buona idea, poiché può portare a effetti collaterali indesiderati.

bar ? () : baz();

In questo caso, () non fa nulla, mentre baz fa qualcosa. Ma hai solo reso il codice meno chiaro. Preferirei un codice più dettagliato che sia più chiaro e più facile da mantenere.

Inoltre, questo ha poco senso:

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

poiché () non ha alcun tipo di ritorno (è void) e baz ha un tipo di ritorno che è sconosciuto al punto di chiamata in questo esempio. Se non sono d'accordo, il compilatore si lamenterà e ad alta voce.


2

Se sei preoccupato per la verbosità del tuo codice, lo scriverei piuttosto che cercare di abusare delle espressioni.

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

Non sto abusando delle espressioni, sto solo pensando!
Ahmed Ghoneim

1

il?: è l'operatore dell'itinerario. (credo di averlo scritto correttamente) ed è semplice da usare. come in un predicato booleano? iftrue: ifalse; Ma devi avere un rvalue / lvalue come in rvalue = predicate? iftrue: iffalse;

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

se x fosse minore di 7, verrei assegnato x, altrimenti sarei 7.

puoi anche usarlo in un ritorno, come in return x < 7 ? x : 7;

di nuovo, come sopra, questo avrebbe lo stesso effetto.

quindi, Source = Source == value ? Source : string.Empty;credo sia quello che stai cercando di ottenere.


6
Mi piace. L' operatore dell'itinerario : ti aiuta ad andare da A a B ... o da A a C ... a seconda di A.
Rick Sladkey

Sì, significa ternario. Ma il nome corretto è "condizionale".
Erick G. Hagstrom


0

Non penso che tu possa essere un operatore e si supponga di restituire l'uno o l'altro. Non è la sostituzione dell'istruzione if else, sebbene possa essere utilizzata per questo in alcuni casi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.