(OrElse e Or) e (AndAlso e E) – Quando usar?

Qual é a diferença entre (OrElse e Or) e (AndAlso e And)? Existe alguma diferença em suas performances, digamos que o benefício de correção? Existe alguma situação que eu não deveria usar OrElse e AndAlso?

Or/And sempre avaliará as expressões e retornará um resultado. Eles não estão em curto-circuito.

OrElse/AndAlso estão em curto-circuito . A expressão correta só é avaliada se o resultado não puder ser determinado a partir da avaliação da expressão esquerda sozinha. (Isso significa: OrElse só avaliará a expressão correta se a expressão esquerda for falsa e AndAlso só avaliará a expressão correta se a expressão esquerda for verdadeira.)

Supondo que nenhum efeito colateral ocorra nas expressões e as expressões não sejam dependentes (e qualquer sobrecarga de execução seja ignorada), elas são as mesmas.

No entanto, em muitos casos, as expressões são dependentes. Por exemplo, queremos fazer algo quando uma lista não é nada e tem mais de um elemento:

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

Isso também pode ser usado para evitar um cálculo “caro” (ou efeitos colaterais, ick!):

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

Pessoalmente, acho que AndAlso e OrElse são os operadores corretos para usar em todos, mas o 1% – ou menos, espero! – dos casos em que é desejado um efeito secundário.

Codificação feliz.


1 Uma exceção lançada na primeira expressão impedirá que a segunda expressão seja avaliada, mas isso dificilmente será surpreendente.

Além do curto-circuito mencionado nas outras respostas, Or / And são utilizáveis ​​como operadores bit a bit, onde OrElse / AndAlso não são. Operações bit a bit incluem a combinação de valores de enums Flags, como a enumeração FileAttributes, onde você pode indicar que um arquivo é somente leitura e oculto por FileAttributes.ReadOnly Or FileAttributes.Hidden

A diferença é que o OrElse e o AndAlso terão um curto-circuito baseado na primeira condição, o que significa que se a primeira condição não passar, a segunda (ou mais) condição não será avaliada. Isso é particularmente útil quando uma das condições pode ser mais intensa que a outra.

Exemplo onde Or está bem (ambas as condições avaliadas):

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

Realmente não importa o caminho que eles são avaliados

O seguinte AndAlso é útil porque a segunda condição pode falhar

 If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then 

Isso permite que a primeira condição verifique se o object foi definido e somente se ele foi definido irá verificar o database (ou alguma outra tarefa). Se isso tivesse sido uma palavra-chave comum, ambos seriam avaliados.

@ Gideon – feliz por alguém ter apontado isso. Aqui está um teste simples que mostra o impacto dramático do 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