(OrElse 和 Or) 和 (AndAlso 和 And) - 何时使用?

发布于 2024-12-20 01:24:35 字数 101 浏览 1 评论 0原文

(OrElse 和 Or) 和 (AndAlso 和 And) 之间有什么区别? 他们的表现有什么不同吗,比如说正确性的好处?有什么情况我不应该使用 OrElse 和 AndAlso 吗?

What is the difference between (OrElse and Or) and (AndAlso and And)?
Is there any difference in their performances, let say the correctness benefit?? Is there any situation that I shoudn't use OrElse and AndAlso?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

魂ガ小子 2024-12-27 01:24:35

Or/And总是计算两个1表达式,然后返回结果。它们没有短路。

OrElse/AndAlso短路。仅当无法仅根据左侧表达式的求值确定结果时,才求值右侧表达式。 (这意味着:OrElse 仅在左侧表达式为 false 时才会计算右侧表达式,而 AndAlso 仅在左侧表达式为 true 时才会计算右侧表达式。)

假设表达式中没有副作用发生并且表达式不依赖(并且忽略任何执行开销),那么它们是相同的。

然而,在许多情况下,表达式是相关的。例如,当列表不为空且具有多个元素时,我们想要做某事:

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

这也可以用于避免“昂贵”的计算(或副作用,恶心!):

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

就我个人而言,我发现 < code>AndAlso 和 OrElse 是除 1% 或更少之外的所有操作符中使用的正确运算符,希望如此! - 需要副作用的情况。

快乐编码。


1 第一个表达式中抛出的异常将阻止第二个表达式的计算,但这不足为奇..

Or/And will always evaluate both1 the expressions and then return a result. They are not short-circuiting.

OrElse/AndAlso are short-circuiting. The right expression is only evaluated if the outcome cannot be determined from the evaluation of the left expression alone. (That means: OrElse will only evaluate the right expression if the left expression is false, and AndAlso will only evaluate the right expression if the left expression is true.)

Assuming that no side effects occur in the expressions and the expressions are not dependent (and any execution overhead is ignored), then they are the same.

However, in many cases it is that the expressions are dependent. For instance, we want to do something when a List is not-Nothing and has more than one element:

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

This can also be used to avoid an "expensive" computation (or side-effects, ick!):

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

Personally, I find that AndAlso and OrElse are the correct operators to use in all but the 1% - or less, hopefully! - of the cases where a side-effect is desired.

Happy coding.


1 An Exception thrown in the first expression will prevent the second expression from being evaluated, but this should hardly be surprising ..

坐在坟头思考人生 2024-12-27 01:24:35

除了其他答案中提到的短路之外, Or/And 还可用作按位运算符,其中 OrElse/AndAlso 不是。按位运算包括组合 Flags 枚举的值,例如 FileAttributes 枚举,您可以在其中通过 FileAttributes.ReadOnly 或 FileAttributes.Hidden 指示文件既是只读的又是隐藏的

Besides the short-circuiting mentioned in the other answers, Or/And are usable as bitwise operators where OrElse/AndAlso are not. Bitwise operations include combining values of Flags enums, such as the FileAttributes enumeration where you might indicate a file is both read only and hidden by FileAttributes.ReadOnly Or FileAttributes.Hidden

囍孤女 2024-12-27 01:24:35

不同之处在于 OrElse 和 AndAlso 会根据第一个条件进行短路,这意味着如果第一个条件不通过,则不会评估第二个(或更多)条件。当其中一种情况可能比另一种情况更严重时,这尤其有用。

Or 很好的示例(两个条件都被评估):

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

以哪种方式评估它们并不重要

下面的 AndAlso 很有用,因为第二个条件可能会失败

If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then

这允许对于第一个条件,检查对象是否已设置,并且只有已设置,才会去检查数据库(或其他任务)。如果这是一个普通的 And 关键字,则两者都会被评估。

The difference is that OrElse and AndAlso will short-circuit based on the first condition, meaning that if the first condition doesn't pass, the second (or more) conditions will not be evaluated. This is particularly useful when one of the conditions might be more intensive than the other.

Example where Or is fine (both conditions evaluated):

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

It really doesn't matter which way around they are evaluated

The following AndAlso is useful because the second condition might fail

If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then

This allows for the first condition to check whether the object has been set and only if it has been set will go and check the database (or some other task). If this had been a plain And keyword, both would be evaluated.

近箐 2024-12-27 01:24:35

@Gideon - 很高兴有人指出这一点。这是一个简单的测试,显示了 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

@Gideon - glad someone pointed that out. Here is a simple test that shows the dramatic impact of 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文