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

(OrElse和Or)和(AndAlso和And)有什么区别? 他们的performance有没有什么区别,说的正确性好处? 有什么情况我不应该使用OrElse和AndAlso?

Or/And并将始终评估两个expression式,然后返回结果。 他们不是短路。

OrElse/AndAlso也是短路 。 只有在评估结果不能单独评估左侧expression时才能评估正确的expression。 (这意味着:如果左expression式为假,则AndAlso将仅评估正确的expression式,而且如果左expression式为真, AndAlso将仅评估正确的expression式。

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

但是,在许多情况下,expression式相关的。 例如,当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 

就我个人而言,我发现AndAlsoOrElse都是正确的运营商,但只有1%或更less,希望! – 在需要副作用的情况下。

快乐的编码。


1在第一个expression式中引发的exception将阻止第二个expression式被评估,但这应该不会令人惊讶。

除了在其他答案中提到的短路之外, 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 

这允许第一个条件检查对象是否已经被设置,并且只有在已经设置的情况下才会去检查数据库(或其他任务)。 如果这是一个简单的关键字,都将被评估。

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