Valutazione dell'espressione da sinistra a destra
Domanda
In C # è garantito che le espressioni vengano valutate da sinistra a destra?
Ad esempio:
myClass = GetClass();
if (myClass == null || myClass.Property > 0)
continue;
Esistono lingue non conformi?
Soluzione
In realtà ti riferisci a una funzione del linguaggio chiamata " espressioni logiche di cortocircuito " ;:
Ciò significa che: quando il risultato di un'espressione logica non può più cambiare, ad es. quando è chiaro che l'espressione valuterà "vero" o " false " in ogni caso, le parti rimanenti dell'espressione non verranno valutate.
Ad esempio, C #, Java o JavaScript lo fanno e puoi fare affidamento su di esso in quelle lingue (per rispondere alla tua domanda).
Nel tuo caso, se MyClass non è null:
-
MyClass == null
restituisce false - poiché è un " o " espressione, la seconda parte può ancora modificare il risultato, quindi viene valutato
-
myClass.Property > 0
determina il risultato finale
se MyClass è null:
-
MyClass == null
restituisce true - poiché è un " o " espressione, non importa cosa segue
- non viene più eseguita alcuna valutazione, il risultato finale è vero
Esistono lingue che non cortocircuitano le espressioni logiche. Il VB classico è un esempio, qui " myClass.Property > 0 " verrebbe valutato e produrrebbe un errore se MyClass fosse null (chiamato " Nothing " in VB).
Altri suggerimenti
Il corto circuito è descritto nella sezione 7.11 della specifica C # 3.0:
L'operazione x || y corrisponde a l'operazione x | y, tranne che y è valutato solo se x non è vero.
Quindi sì, stai bene.
Per quanto riguarda le altre lingue, non mi piace parlare in tutte . In VB.NET, puoi usare OrElse e AndAlso che sono in corto circuito, ma semplici Or e E non lo sono.
Ma fai attenzione:
se hai qualcosa del genere
sprintf (buf, "% s% s " ;, func1 (& amp; var), func2 (& amp; var));
con effetti collaterali su var, non è definito (in C, non sono sicuro se l'ordine di valutazione è definito in altre lingue), in quale ordine func1 () e func2 () sono eseguiti (dipende, in quale ordine (sinistra o destra) gli argomenti vengono messi in pila e valutati da lì.
L'ordine di valutazione dipende dall'operatore, in questo caso il valore booleano o ( ||
) è definito come ciò che viene comunemente chiamato cortocircuito , per realizzare costrutti come questo.
Gli operatori e / o in lingue come Ada, Visual Basic e Pascal non cortocircuitano. Forniscono operatori extra per consentire tale funzionalità, come " e quindi " e " oppure " in Ada.
Non sono sicuro, sei davvero interessato all'ordine o alla valutazione del corto circuito?
Non sono sicuro al 100%, ma per quanto ne so l'ordine di valutazione sarà sempre lo stesso in C # (e presumo la maggior parte se non tutti i linguaggi .net). La valutazione del corto circuito funziona come spiegato nelle risposte precedenti.
Tuttavia, in C # puoi scegliere di non cortocircuitare usando operatori semplici (& amp; anziché & amp; & amp;). Normalmente si desidera cortocircuitare, ma potrebbe essere un caso in cui si desidera eseguire tutte le valutazioni.
Python ha operatori o
e e
in corto circuito.
In Java e Haskell & amp; & amp; e || anche cortocircuito.
Interessante a parte: in Haskell questo viene naturalmente con il linguaggio (puoi definire i tuoi operatori che lo fanno), mentre in Java e C # è specifico per quei due operatori.
In realtà il corto circuito fa parte, ma devi anche sapere se il linguaggio garantisce una valutazione da sinistra a destra di quelli. Ad esempio C (ANSI, ISO, C99) NON garantisce una valutazione da sinistra a destra. Nel codice di esempio sarebbe possibile controllare il valore di Property prima di controllare NULL o eseguire entrambe le operazioni contemporaneamente ... la maggior parte dei compilatori non lo fa, ma non c'è nulla che gli impedisca di farlo e di essere pienamente conforme alle specifiche. Ti dice anche di NON scrivere questo codice per questo.