Domanda

Ahh, non basta amare un buon abusi ternario? :) Si consideri la seguente espressione:

true ? true : true ? false : false

Per quelli di voi che sono ormai assolutamente perplessi, posso dirvi che questo restituisce true . In altre parole, è equivalente a questo:

true ? true : (true ? false : false)

Ma è affidabile? Posso essere sicuro che in alcune circostanze non si arriverà a questo:

(true ? true : true) ? false : false

Qualcuno potrebbe dire - bene, basta aggiungere tra parentesi, allora o non usare del tutto - dopo tutto, è un fatto ben noto che gli operatori ternari sono il male

!

Certo che sono, ma ci sono alcune circostanze, quando in realtà hanno un senso. Per i più curiosi - sto strizzare il codice che mette a confronto due oggetti da una serie di proprietà. Sarebbe molto bello se ho freddo scrivo in questo modo:

obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
obj1.Prop4.CompareTo(obj2.Prop4)

chiaro e conciso. Ma non dipende all'associatività operatore ternario lavorando come nel primo caso. Parentesi sarebbe solo fare gli spaghetti fuori di esso.

Quindi - è questo specificato da nessuna parte? Non riuscivo a trovarlo.

È stato utile?

Soluzione

Sì, si può fare affidamento su questo (non solo in C #, ma a tutto (che io sappia) altre lingue ( eccetto PHP ... vai figura) con un operatore condizionale) e il vostro caso d'uso è in realtà una pratica abbastanza comune, anche se alcune persone detestano esso.

La sezione pertinente in ECMA-334 (C # standard) è 14.13 §3:

  

L'operatore condizionale è giusto associativa, che significa che le operazioni sono raggruppate da destra a sinistra.   [Esempio: Un'espressione della forma a ? b : c ? d : e viene valutato come a ? b : (c ? d : e). fine   Esempio]

Altri suggerimenti

Se devi chiedere, non lo fanno. Chiunque legga il codice sarà solo passare attraverso lo stesso processo che hai fatto, più e più volte, qualsiasi volta che il codice ha bisogno di essere guardato. Debug tale codice non è divertente. Alla fine sarà solo essere modificato per usare le parentesi in ogni caso.

Re: "Prova a scrivere il tutto con parentesi"

result = (obj1.Prop1 != obj2.Prop1 ? obj1.Prop1.CompareTo(obj2.Prop1) :
         (obj1.Prop2 != obj2.Prop2 ? obj1.Prop2.CompareTo(obj2.Prop2) :
         (obj1.Prop3 != obj2.Prop3 ? obj1.Prop3.CompareTo(obj2.Prop3) :
                                     obj1.Prop4.CompareTo(obj2.Prop4))))

Chiarimento:

  • "Se si devi chiedere, non lo fanno."
  • "Chiunque legga tuo il codice ..."

A seguito delle convenzioni comuni in un progetto è il modo per mantenere la coerenza, che migliora la leggibilità. Sarebbe un'impresa inutile pensare di poter scrivere codice leggibile a tutti, compresi coloro che non conoscono nemmeno la lingua!

Il mantenimento della coerenza all'interno di un progetto, però, è un obiettivo utile, e non seguendo convenzioni accettate di un progetto porta a dibattito che toglie risolvere il vero problema. Coloro che leggono il codice si prevede di essere a conoscenza delle convenzioni comuni e accettati utilizzati nel progetto, e sono anche suscettibili di essere qualcun altro lavorando direttamente su di esso. Se non li conoscete, allora dovrebbero essere loro apprendimento e devono sapere a chi rivolgersi per chiedere aiuto.

Detto questo, se utilizzando espressioni ternari senza parentesi è una convenzione comune e accettato nel progetto, quindi utilizzarlo, con tutti i mezzi! che si doveva chiedere indica che non è comune o accettato nel progetto. Se si desidera modificare le convenzioni nel progetto, poi fare il evidentemente inequivocabile, marcare giù come qualcosa da discutere con altri membri del progetto, e andare avanti. Ecco che significa usare parentesi o utilizzando if-else.

Un ultimo punto su cui riflettere, se alcuni del codice sembra intelligente per voi:

  

Il debugging è due volte più duro come la scrittura del codice, in primo luogo. Pertanto, se si scrive il codice come abilmente possibile, si è, per definizione, non abbastanza intelligente per eseguire il debug. - Brian W. Kernighan

L'affermazione che le parentesi sminuire la leggibilità del codice è un falso presupposto. Trovo l'espressione tra parentesi molto più chiaro. Personalmente, vorrei usare le parentesi e / o riformattare su più righe per migliorare la leggibilità. La riformattazione su più righe e l'utilizzo di rientro può anche ovviare alla necessità di parentesi. E, sì, si può fare affidamento sul fatto che l'ordine di associazione è deterministico, da destra a sinistra. Questo permette l'espressione da valutare da sinistra a destra nella maniera prevista.

obj1.Prop1 != obj2.Prop1
     ? obj1.Prop1.CompareTo(obj2.Prop1)
     : obj1.Prop2 != obj2.Prop2
           ? obj1.Prop2.CompareTo(obj2.Prop2)
           : obj1.Prop3 != obj2.Prop3
                  ? obj1.Prop3.CompareTo(obj2.Prop3)
                  : obj1.Prop4.CompareTo(obj2.Prop4);

Fare riferimento a MSDN: http://msdn.microsoft.com/en- us / library / ty67wk28% 28VS.80% 29.aspx

"Se la condizione è vera, prima espressione viene valutata e diventa il risultato;.. Se falsa, la seconda espressione viene valutata e diventa il risultato solo una delle due espressioni è sempre valutate"

x = cond1 ? result1
  : cond2 ? result2
  : cond3 ? result3
  : defaultResult;

vs

if (cond1) x = result1;
else if (cond2) x = result2;
else if (cond3) x = result3;
else x = defaultResult;

Mi piace il primo.

Sì, si può contare su condizionale associatività dell'operatore. La sua nel manuale, al link gentilmente fornito da DCP, ha dichiarato come "L'operatore condizionale è giusto-associativo", con un esempio. E, come lei ha suggerito, io e gli altri d'accordo, il fatto che si può fare affidamento su di esso permette codice più chiaro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top