Domanda

In C#, (e sentitevi liberi di rispondere per le altre lingue), che fine fa il runtime di valutare una logica di istruzione?

Esempio:

DataTable myDt = new DataTable();
if (myDt != null && myDt.Rows.Count > 0)
{
    //do some stuff with myDt
}

L'istruzione che fa il runtime valutare prima

myDt != null

o:

myDt.Rows.Count > 0

?

C'è un momento in cui il compilatore non avrebbe mai valutare la dichiarazione indietro?Forse quando un operatore "or" è coinvolto?


e ' noto come un logico bit a bit operatore e sarà sempre valutare tutte le sotto-espressioni

Che cosa è un buon esempio di quando utilizzare l'operatore, invece di "corto circuito booleano"?

È stato utile?

Soluzione

C# :Da sinistra a destra, e l'elaborazione viene interrotta se una non-partita (falso) è stato trovato.

Altri suggerimenti

"C# :Da sinistra a destra, e l'elaborazione viene interrotta se una partita (restituisce true) è stato ritrovato".

Pecore Zombie è sbagliato, non basta rep giù di voto.

La domanda riguarda l'operatore&&, non l'operatore||.

Nel caso di && valutazione si ferma se un FALSO è trovato.

In caso di || valutazione si se VERO è trovato.

Mi rendo conto che questa domanda è già stato risposto, ma vorrei gettare un altro po ' di informazioni relative all'argomento.

In linguaggi come C++, in cui si può effettivamente sovraccaricare il comportamento di && e || operatori, è altamente raccomandato che si non fare questo.Questo è perché quando si esegue l'overload questo comportamento, si finisce per forzare la valutazione di entrambi i lati dell'operazione.Questo fa due cose:

  1. Si rompe il pigro meccanismo di valutazione, perché il sovraccarico è una funzione che deve essere richiamato, e, di conseguenza, entrambi i parametri sono valutati prima di chiamare la funzione.
  2. L'ordine di valutazione di tali parametri non è garantita e può essere compilatore specifico.Di conseguenza, gli oggetti non si comportano nello stesso modo, come avviene negli esempi riportati nelle domande/risposte precedenti.

Per maggiori informazioni, leggi di Scott Meyers' libro Più Efficace C++.Evviva!

vb.net

if( x isNot Nothing AndAlso x.go()) then
  1. La valutazione è effettuata da sinistra a destra
  2. AndAlso l'operatore assicura che solo se il lato sinistro è VERO, il lato destro verrà valutato (molto importante, dal momento che ifx è nulla x.andare in crash)

Si può utilizzare E invece ofAndAlso in vb.in questo caso il lato sinistro viene valutata prima, ma il lato destro sarà valutato a prescindere dal risultato.

Best Practice:Utilizzare sempre AndAlso, a meno che non hai una buona ragione per cui non.


È stato chiesto in un follow-up perché o quando vorresti essere utilizzato da chiunque E invece di AndAlso (o & invece &&): Ecco un esempio:

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

In questo caso, voglio init X e Y.Y deve essere inizializzato in ordine di y.DoDance per essere in grado di eseguire.Tuttavia, in funzione init() sto facendo anche alcuni extra cosa come il controllo di un socket aperto, e solo se funziona ok, per entrambi, Io dovrei andare avanti e fare l'x.processo(y).

Di nuovo, questo probabilmente non è necessario e non è elegante nel 99% dei casi, che è il motivo per cui ho detto che il valore di default dovrebbe essere quello di utilizzare AndAlso.

@shsteimer

Il concetto di pudore si fa riferimento è l'overload dell'operatore.nella seguente affermazione:...Una è valutata in primo luogo, se è false, B non è mai valutato.Lo stesso vale per

Non è l'overload dell'operatore.L'overload dell'operatore è il termine dato per che consente di definire il comportamento per gli operatori, quali*, +, =, e così via.

Ciò permette di scrivere il proprio "Registro di classe", e quindi fare

a = new Log(); // Log class overloads the + operator
a + "some string"; // Call the overloaded method - otherwise this wouldn't work because you can't normally add strings to objects.

Facendo questo

a() || b() // be never runs if a is true

è in realtà chiamato Corto Circuito Di Valutazione

ZombieSheep è morto-on.L'unico "gotcha" che potrebbe essere in attesa che questo è vero solo se si utilizza l'operatore&&.Quando si utilizza l'operatore&, entrambe le espressioni saranno valutati ogni momento, a prescindere se uno o entrambi restituiscono false.

if (amHungry & whiteCastleIsNearby)
{
   // The code will check if White Castle is nearby
   // even when I am not hungry
}

if (amHungry && whiteCastleIsNearby)
{
   // The code will only check if White Castle is nearby
   // when I am hungry
}

Nota che c'è una differenza tra && e & per quanto riguarda la quantità di espressione viene valutata.

&& è conosciuto come un corto circuito booleano E, e, come notato da altri qui, interrompere in anticipo se il risultato può essere determinato prima di tutto il sub-vengono valutate le espressioni.

e ' noto come un logico bit a bit operatore e sarà sempre valutare tutte le sotto-espressioni.

In quanto tale:

if (a() && b())

Solo chiamata b se un restituisce vero.

tuttavia, questo:

if (a() & b())

Sarà sempre chiamare un e b, anche se il risultato della chiamata un è falsa e, quindi, noto per essere false indipendentemente dal risultato della chiamata b.

Questa stessa differenza esiste per il || e | o operatori.

Alcune lingue sono situazioni interessanti, in cui le espressioni sono eseguite in un ordine diverso.Io sono specificamente pensando di Ruby, ma sono sicuro che hanno preso in prestito da altre parti (probabilmente Perl).

Espressioni, nella logica di soggiorno da sinistra a destra, ma per esempio:

puts message unless message.nil?

Sopra valuterà "il messaggio.nil?", quindi se restituisce false (a meno che non è come se, tranne che viene eseguita quando la condizione è false al posto di true)", mette messaggio" eseguirà, che stampa il contenuto del messaggio variabile per lo schermo.

È un modo interessante per strutturare il codice, a volte...Personalmente mi piace usarlo per brevi fodere 1 come sopra.

Edit:

Per renderlo un po ' più chiara, di cui sopra, è la stessa:

unless message.nil?
  puts message
end

La sinistra, poi si ferma se è null.

Edit:In vb.net si valuteranno sia e, possibilmente, di gettare un errore, a meno che non si utilizza AndAlso

Il concetto di pudore si fa riferimento è l'overload dell'operatore.nella seguente affermazione:

if( A && B){
    // do something
}

Una è valutata in primo luogo, se è false, B non è mai valutato.Lo stesso vale per

if(A || B){
    //do something
}

Una è valutata in primo luogo, se restituisce true, B non è mai valutato.

Questo concetto, sovraccarico, si applica a (credo) tutti i linguaggi di tipo C, e molti altri.

Nopes, almeno il compilatore C# non funziona con le versioni precedenti (in entrambi i && o ||).È da sinistra a destra.

Quando le cose sono tutti in linea, sono eseguite da sinistra a destra.

Quando le cose sono nidificati, sono eseguite internamente-per-esterno.Questo può sembrare confuso, come di solito cosa "intima" è sul lato destro della linea, in modo che sembra che sta andando all'indietro...

Per esempio

a = Foo( 5, GetSummary( "Orion", GetAddress("Orion") ) );

Succedono cose come questa:

  • Chiamata GetAddress con il letterale "Orion"
  • Chiamata GetSummary con il letterale "Orion" e il risultato di GetAddress
  • Chiamata Foo con il letterale 5 e il risultato di GetSummary
  • Assegnare questo valore per a

Mi piace Orione risposte.Vorrei aggiungere due cose:

  1. Da sinistra a destra si applica ancora prima
  2. L'interno a esterno, per garantire che tutti gli argomenti sono stati risolti prima di chiamare la funzione

Supponiamo di avere il seguente esempio:

a = Foo(5, GetSummary("Orion", GetAddress("Orion")),
           GetSummary("Chris", GetAddress("Chris")));

Ecco l'ordine di esecuzione:

  1. GetAddress("Orion")
  2. GetSummary("Orion", ...)
  3. GetAddress("Chris")
  4. GetSummary("Chris", ...)
  5. Foo(...)
  6. Assegna a a

Io non posso parlare di C#'s requisiti di legge (anche se ho fatto il test un simile esempio di utilizzo di Mono prima di scrivere questo post), ma l'ordine è garantito in Java.

E giusto per completezza (dal momento che questo è un linguaggio indipendente thread così), ci sono linguaggi come C e C++, in cui l'ordine non è garantita se non c'è una sequenza in punto.Riferimenti: 1, 2.In risposta il thread in questione e, comunque, && e || sono la sequenza di punti in C++ (a meno di sovraccarico;vedi anche GU eccellente risposta).Così alcuni esempi:

  • foo() && bar()
  • foo() & bar()

Nel && caso, foo() è garantito per l'esecuzione prima bar() (se quest'ultimo è gestito a tutti), dal momento che && è una sequenza di punto.Nel & caso, non tale garanzia viene effettuata (in C e C++), e infatti bar() prima foo(), o viceversa.

Che cosa è un buon esempio di quando utilizzare l'operatore, invece di "corto circuito booleano"?

Si supponga di avere bandiere, dire per gli attributi di file.Supponiamo di aver definito LEGGERE come 4, SCRIVERE come 2, e EXEC come 1.In binario, che è:

READ  0100  
WRITE 0010  
EXEC  0001

Ogni indicatore ha un po ' insieme, e ognuno è unico.Gli operatori a livello di bit consentono di combinare questi parametri:

flags = READ & EXEC; // value of flags is 0101

Ho sentito da qualche parte che i compilatori di lavorare con le versioni precedenti, ma non sono sicuro di quanto questo sia vero.

Si utilizza, e quando avete voglia di valutare tutte le sotto-espressioni, probabilmente perché hanno effetti collaterali che si desidera, anche se il risultato finale sarà false e, quindi, di non eseguire il vostro quindi parte del vostro se-istruzione.

Nota che & e | funziona per entrambi i bit a bit maschere e i valori booleani e non è solo per le operazioni bit per bit.Sono chiamato bit a bit, ma essi sono definiti per entrambi interi, booleani e i tipi di dati in C#.

@csmba:

È stato chiesto in un follow-up perché o quando vorresti essere utilizzato da chiunque E invece di AndAlso (o & invece &&):Ecco un esempio:

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

In questo caso, voglio init X e Y.Y deve essere inizializzato in ordine di y.DoDance per essere in grado di eseguire.Tuttavia, in funzione init() sto facendo anche alcuni extra cosa come il controllo di un socket aperto, e solo se funziona ok, per entrambi, devo andare avanti e fare l'x.processo(y).

Credo che questo sia piuttosto confusa.Anche se il tuo esempio funziona, non è il tipico caso per l'utilizzo di And (e probabilmente vorrei scrivere questo in modo diverso per rendere più chiara). And (& nella maggior parte delle altre lingue) è in realtà l'operazione e il funzionamento.Si dovrebbe utilizzare per calcolare po ' di operazioni, ad esempio l'eliminazione di un bit di flag o il mascheramento e il test di bandiere:

Dim x As Formatting = Formatting.Bold Or Formatting.Italic
If (x And Formatting.Italic) = Formatting.Italic Then
    MsgBox("The text will be set in italic.")
End If

D linguaggio di programmazione Non da sinistra a destra di valutazione con corto circuito e non permettere un sovraccarico del && e '||' operatori.

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