(OrElse and Or)と(AndAlso and And)の違いは何ですか?彼らのパフォーマンスに違いはありますか? OrElseとAndAlsoを使用しないといけない状況はありますか?
Or/And
はalways評価both1 式を実行し、結果を返します。それらはnot短絡です。
OrElse/AndAlso
は 短絡 です。右式は、左式のみの評価から結果を判断できない場合にのみ評価されます。 (つまり、OrElse
は左の式が偽の場合にのみ右の式を評価し、AndAlso
は左の式が真の場合にのみ右の式を評価します。)
副次的影響が式に発生せず、式が依存していないと仮定します(および実行オーバーヘッドは無視されます)、それらは同じです。
ただし、多くの場合、式はに依存します。たとえば、Listがnot-Nothingであり、複数の要素がある場合に何かを実行します。
If list IsNot Nothing AndAlso list.Length > 0 Then .. 'list has stuff
これは、「高価な」計算(または、副作用!)を避けるためにも使用できます。
If Not Validate(x) OrElse Not ExpensiveValidate(x) Then .. 'not valid
個人的には、AndAlso
とOrElse
は、1%以外のすべてで使用するcorrect演算子であることがわかりました-または少なく、できれば! -副作用が望ましい場合.
ハッピーコーディング。
1 最初の式で例外がスローされると、2番目の式が評価されなくなりますが、これは驚くべきことではありません。
他の回答に記載されている短絡に加えて、Or
/And
はビット演算子として使用できますが、OrElse
/AndAlso
は使用できません。ビット単位の操作には、Flags列挙値の組み合わせが含まれます。たとえば、 FileAttributes 列挙では、ファイルが読み取り専用であり、FileAttributes.ReadOnly Or FileAttributes.Hidden
によって非表示になっていることを示します。
違いは、OrElseとAndAlsoは最初の条件に基づいて短絡することです。つまり、最初の条件が満たされない場合、2番目(またはそれ以上)の条件は評価されません。これは、条件の1つが他の条件よりも集中する場合に特に役立ちます。
Or
が適切な例(両方の条件が評価されます):
If Name = "Fred" Or Name = "Sam" Then
彼らがどのように評価されるかは本当に関係ありません
次のAndAlso
は、2番目の条件が失敗する可能性があるため便利です。
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