(OrElse и Or) и (AndAlso и And) - Когда использовать?
В чем разница между (OrElse и Or) и (AndAlso и And)? Есть ли какая-то разница в их выступлениях, скажем, в пользу правильности?? Есть ли ситуации, в которых я не должен использовать OrElse и AndAlso?
4 ответа
Or/And
всегда будет вычислять оба выражения и затем возвращать результат. Они не закорочены.
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 Исключение, выданное в первом выражении, предотвратит оценку второго выражения, но это вряд ли должно удивлять.
Помимо короткого замыкания, упомянутого в других ответах, Or
/ And
могут использоваться как побитовые операторы, где OrElse
/ AndAlso
не. Побитовые операции включают объединение значений перечислений Flags, таких как перечисление FileAttributes, где вы можете указать, что файл доступен только для чтения и скрыт FileAttributes.ReadOnly Or FileAttributes.Hidden
Разница в том, что OrElse и AndAlso будут закорачиваться на основе первого условия, что означает, что если первое условие не пройдет, второе (или более) условие не будет оцениваться. Это особенно полезно, когда одно из условий может быть более интенсивным, чем другое.
Пример где Or
хорошо (оба условия оценены):
If Name = "Fred" Or Name = "Sam" Then
Это действительно не имеет значения, каким образом они оцениваются
Следующие AndAlso
полезно, потому что второе условие может потерпеть неудачу
If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then
Это позволяет при первом условии проверить, был ли установлен объект, и только если он был установлен, пойдет и проверит базу данных (или какую-либо другую задачу). Если бы это было просто And
ключевое слово, оба будут оценены.
@ Гидеон - рад, что кто-то указал на это. Вот простой тест, который показывает драматическое влияние 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