(OrElse и Or) и (AndAlso и And) - Когда использовать? - PullRequest
44 голосов
/ 07 декабря 2011

В чем разница между (OrElse и Or) и (AndAlso и And)? Есть ли разница в их выступлениях, скажем так, в пользу правильности ?? Есть ли ситуации, в которых я не должен использовать OrElse и AndAlso?

Ответы [ 4 ]

67 голосов
/ 07 декабря 2011

Or/And будет всегда оценивать оба 1 выражения и затем возвращает результат. Они не короткозамкнуты.

OrElse/AndAlso являются короткозамкнутыми . Правое выражение оценивается, только если результат не может быть определен на основе оценки только левого выражения. (Это означает, что OrElse будет оценивать правое выражение только в том случае, если левое выражение ложно, а AndAlso будет оценивать правое выражение только в том случае, если левое выражение истинно.)

Если предположить, что никаких побочных эффектов не возникает в выражениях, а выражения не являются зависимыми (и любые издержки выполнения игнорируются), то они одинаковы.

Однако во многих случаях выражения зависят от . Например, мы хотим что-то сделать, когда List не равен Nothing и имеет более одного элемента:

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

Это также можно использовать, чтобы избежать "дорогих" вычислений (или побочных эффектов, ick!):

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

Лично я считаю, что AndAlso и OrElse являются правильными операторами, которые можно использовать во всех случаях, кроме 1% - или, надеюсь, меньше! - из случаев, когда побочный эффект является желательным .

Удачного кодирования.


1 Исключение, сгенерированное в первом выражении, предотвратит оценку второго выражения, но это вряд ли должно удивлять.

10 голосов
/ 07 декабря 2011

Помимо короткого замыкания, упомянутого в других ответах, Or / And могут использоваться как побитовые операторы, а OrElse / AndAlso - нет. Побитовые операции включают объединение значений перечислений Flags, таких как перечисление FileAttributes , где можно указать, что файл доступен только для чтения и скрыт FileAttributes.ReadOnly Or FileAttributes.Hidden

4 голосов
/ 07 декабря 2011

Разница в том, что OrElse и AndAlso будут закорачиваться на основе первого условия, что означает, что если первое условие не пройдет, второе (или более) условие не будет оценено. Это особенно полезно, когда одно из условий может быть более интенсивным, чем другое.

Пример, где Or в порядке (оба условия оценены):

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

Не имеет значения, с какой стороны они оцениваются

Следующее AndAlso полезно, поскольку второе условие может быть не выполнено

If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then

Это позволяет при первом условии проверить, был ли установлен объект, и только если он был установлен, пойдет и проверит базу данных (или какую-либо другую задачу). Если бы это было простое ключевое слово And, оба были бы оценены.

2 голосов
/ 07 декабря 2011

@ Гидеон - рад, что кто-то указал на это. Вот простой тест, который показывает драматическое влияние 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
...