vb.net-(OrElse和Or)和(AndAlso和And)-何时使用?
(OrElse和Or)和(AndAlso和And)有什么区别?他们的表现有什么不同,可以说正确性好处吗? 有没有我不应该使用OrElse和AndAlso的情况?
AndAlso
将始终对两个表达式求值,然后返回结果。 它们不是短路的。
AndAlso
发生短路。 仅当无法仅通过对左表达式的评估无法确定结果时,才对右表达式进行评估。 (这意味着:2973291228810445845825仅在左表达式为false时才评估右表达式,而2973291228810445845826仅在左表达式为true时才评估右表达式。)
假设表达式中没有副作用,并且表达式不相关(并且忽略了任何执行开销),则它们是相同的。
但是,在许多情况下,表达式是从属的。 例如,当List为No-Nothing并且具有多个元素时,我们想做一些事情:
If list IsNot Nothing AndAlso list.Length > 0 Then .. 'list has stuff
这也可以用来避免“昂贵”的计算(或副作用,!):
If Not Validate(x) OrElse Not ExpensiveValidate(x) Then .. 'not valid
就我个人而言,我发现2973291228810445845824和2973291228810445845825是除1%(或更少)以外的所有变量中使用的正确运算符,希望如此! -需要副作用的情况。
快乐的编码。
1在第一个表达式中引发异常将阻止对第二个表达式进行求值,但这并不奇怪。
除了在其他答案中提到的短路外,2973292099866766723328/And
可用作按位运算符,而OrElse
/AndAlso
不可用。 按位操作包括组合Flags枚举的值,例如FileAttributes枚举,在该枚举中您可能会指示文件是只读的,并且被FileAttributes.ReadOnly Or FileAttributes.Hidden
隐藏
区别在于OrElse和AndAlso将基于第一个条件发生短路,这意味着,如果不通过第一个条件,将不会评估第二个(或更多个)条件。 当其中一个条件可能比另一个条件更密集时,这特别有用。
示例And
正常(两个条件均已评估):
If Name = "Fred" Or Name = "Sam" Then
评估它们的方式真的无关紧要
以下2973922456063796224很有用,因为第二个条件可能会失败
If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then
这使第一个条件可以检查是否已设置对象,并且只有在已设置对象的情况下,才可以检查数据库(或其他任务)。 如果这是一个普通的And
关键字,则将对两个关键字都进行评估。
@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