2011-12-07 16 views
41

Qual è la differenza tra (OrElse e Or) e (AndAlso e And)? C'è qualche differenza nelle loro prestazioni, diciamo il vantaggio di correttezza ?? C'è qualche situazione in cui non userò OrElse e AndAlso?(OrElse e Or) e (AndAlso and And) - Quando usare?

+2

possibile duplicato di [? Devo sempre utilizzare gli operatori AndAlso e OrElse] (http://stackoverflow.com/questions/55013/should-i -always-use-the-andalso-and-orelse-operators) –

+0

Appena iniziato a utilizzare VB.NET (la prima volta in molti anni per VB). Sono entrato online solo per fare questa domanda specifica. I miei ringraziamenti a @aer e ai tanti che hanno chiarito con le loro grandi risposte. – Hardryv

risposta

62

Or/And sarà sempre valutare entrambi le espressioni e quindi restituire un risultato. Sono non cortocircuito.

OrElse/AndAlso sono short-circuiting. L'espressione corretta viene valutata solo se il risultato non può essere determinato dalla sola valutazione dell'espressione sinistra. (Ciò significa: OrElse valuterà solo l'espressione giusta se l'espressione di sinistra è falsa, e AndAlso valuterà solo l'espressione giusta se l'espressione a sinistra è vero.)

Supponendo che effetti collaterali si verificano nelle espressioni e le espressioni non dipendono da (e qualsiasi overhead di esecuzione viene ignorato), quindi sono uguali.

Tuttavia, in molti casi è che le espressioni sono dipendenti. Per esempio, vogliamo fare qualcosa quando una lista non-niente e ha più di un elemento: (! O effetti collaterali, sigh)

If list IsNot Nothing AndAlso list.Length > 0 Then .. 'list has stuff 

Questo può essere utilizzato anche per evitare un calcolo "costoso" :

If Not Validate(x) OrElse Not ExpensiveValidate(x) Then .. 'not valid 

Personalmente, trovo che AndAlso e OrElse sono i corretti operatori da utilizzare in tutti, ma l'1% - o meno, si spera! - dei casi in cui un effetto collaterale è desiderato.

Felice codifica.


Un'eccezione gettato la prima espressione impedirà la seconda espressione di essere valutata, ma questo non deve sorprendere ..

4

La differenza è che OrElse e AndAlso saranno-corto circuito base alla prima condizione, nel senso che se la prima condizione non passa, le seconde (o più) condizioni non saranno valutate. Ciò è particolarmente utile quando una delle condizioni potrebbe essere più intensa dell'altra.

Esempio dove Or è soddisfacente (entrambe le condizioni valutati):

If Name = "Fred" Or Name = "Sam" Then 

In realtà non importa quale viceversa vengono valutati

il seguente AndAlso è utile perché la seconda condizione potrebbe riuscire

If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then 

Ciò consente alla prima condizione di verificare se l'oggetto è stato impostato e onl y se è stato impostato andrà a controllare il database (o qualche altra attività). Se questa fosse stata una semplice parola chiave And, entrambi sarebbero stati valutati.

10

Oltre al corto circuito menzionato in altre risposte, Or/And sono utilizzabili come operatori bit dove OrElse/AndAlso non lo sono. Le operazioni bit a bit includono la combinazione di valori di enumerazioni Flags, come l'enumerazione FileAttributes in cui è possibile indicare che un file è solo di sola lettura e nascosto da FileAttributes.ReadOnly Or FileAttributes.Hidden

2

@Gideon - contento che qualcuno lo abbia indicato. Ecco un semplice test che mostra l'impatto drammatico della AndAlso:

Dim tm As New Stopwatch 
    Const tries As Integer = 123456 
    Dim z As Integer = 0 
    Dim s() As String = New String() {"0", "one"} 

    Debug.WriteLine("AndAlso") 
    For x As Integer = 0 To s.Length - 1 
     z = 0 
     tm.Restart() 'restart the stopwatch 
     For y As Integer = 0 To tries 
      If s(x) = x.ToString AndAlso s(x) = y.ToString Then '<<<<<<<<<< 
       z += 1 
      End If 
     Next 
     tm.Stop() 
     Debug.WriteLine(x.ToString.PadRight(3, " "c) & z.ToString.PadRight(10, " "c) & tm.Elapsed.ToString) 
    Next 

    Debug.WriteLine("And") 
    For x As Integer = 0 To s.Length - 1 
     z = 0 
     tm.Restart() 'restart the stopwatch 
     For y As Integer = 0 To tries 
      If s(x) = x.ToString And s(x) = y.ToString Then '<<<<<<<<<< 
       z += 1 
      End If 
     Next 
     tm.Stop() 
     Debug.WriteLine(x.ToString.PadRight(3, " "c) & z.ToString.PadRight(10, " "c) & tm.Elapsed.ToString) 
    Next