2011-12-07 18 views
41

¿Cuál es la diferencia entre (OrElse y Or) y (AndAlso and And)? ¿Hay alguna diferencia en sus actuaciones, digamos que el beneficio de corrección? ¿Hay alguna situación en la que no use OrElse y AndAlso?(OrElse and Or) and (AndAlso and And) - ¿Cuándo usar?

+2

posible duplicado de [? ¿Debo utilizar siempre los operadores AndAlso y OrElse] (http://stackoverflow.com/questions/55013/should-i -siempre-use-the-andalso-and-orelse-operators) –

+0

Acaba de empezar a usar VB.NET (la primera vez en muchos años para VB). Entré en línea solo para hacer esta pregunta específica. Mi agradecimiento a @aer y a la gran cantidad de personas que aclararon con sus excelentes respuestas. – Hardryv

Respuesta

62

Or/And se siempre evaluar ambos las expresiones y luego devolver un resultado. Son no cortocircuitos.

OrElse/AndAlso son short-circuiting. La expresión correcta solo se evalúa si el resultado no puede determinarse a partir de la evaluación de la expresión izquierda sola. (Esto significa: OrElse sólo se evaluará la expresión de la derecha si la expresión de la izquierda es falsa, y AndAlso sólo se evaluará la expresión de la derecha si la expresión izquierda es cierto.)

Suponiendo que sin efectos secundarios se producen en las expresiones y las expresiones no son dependientes (y se ignora cualquier sobrecarga de ejecución), entonces son las mismas.

Sin embargo, en muchos casos es que las expresiones son dependientes. Por ejemplo, queremos hacer algo cuando una lista no-nada y tiene más de un elemento: (! O efectos secundarios, ick)

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

Esto también se puede utilizar para evitar un cálculo "caro" :

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

Personalmente, considero que AndAlsoOrElse y son los correctos operadores a utilizar en todo menos en el 1% - o menos, es de esperar! - de los casos en que se desea un efecto secundario deseado.

Happy coding.


Una excepción lanzada en la primera expresión evitará que la segunda expresión de ser evaluado, pero esto difícilmente debería ser sorprendente ..

4

La diferencia es que OrElse y AndAlso se corta circuito basado en la primera condición, lo que significa que si la primera condición no pasa, la segunda (o más) condiciones no se evaluarán. Esto es particularmente útil cuando una de las condiciones puede ser más intensa que la otra.

Ejemplo Or donde está muy bien (ambas condiciones evaluadas):

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

Realmente no importa qué camino alrededor de ellos se evalúan

los siguientes AndAlso es útil porque la segunda condición puede fallar

If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then 

Esto permite la primera condición para verificar si el objeto se ha configurado y activado y si se ha configurado irá y comprobará la base de datos (o alguna otra tarea). Si esta hubiera sido una palabra clave simple And, ambas serían evaluadas.

10

Además del cortocircuito mencionado en otras respuestas, Or/And son utilizables como operadores de bits, donde OrElse/AndAlso no lo son. Las operaciones de bit a bit incluyen la combinación de valores de enumeraciones de Flags, como la enumeración FileAttributes, donde puede indicar que un archivo es de solo lectura y está oculto por FileAttributes.ReadOnly Or FileAttributes.Hidden

2

@Gideon: me alegro de que alguien lo haya señalado. Aquí está una prueba simple que muestra el impacto dramático de 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