web-dev-qa-db-ja.com

(OrElse and Or)および(AndAlso and And)-いつ使用するか?

(OrElse and Or)と(AndAlso and And)の違いは何ですか?彼らのパフォーマンスに違いはありますか? OrElseとAndAlsoを使用しないといけない状況はありますか?

44
aer

Or/Andalways評価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

個人的には、AndAlsoOrElseは、1%以外のすべてで使用するcorrect演算子であることがわかりました-または少なく、できれば! -副作用が望ましい場合.

ハッピーコーディング。


1 最初の式で例外がスローされると、2番目の式が評価されなくなりますが、これは驚くべきことではありません。

67
user166390

他の回答に記載されている短絡に加えて、Or/Andはビット演算子として使用できますが、OrElse/AndAlsoは使用できません。ビット単位の操作には、Flags列挙値の組み合わせが含まれます。たとえば、 FileAttributes 列挙では、ファイルが読み取り専用であり、FileAttributes.ReadOnly Or FileAttributes.Hiddenによって非表示になっていることを示します。

10

違いは、OrElseとAndAlsoは最初の条件に基づいて短絡することです。つまり、最初の条件が満たされない場合、2番目(またはそれ以上)の条件は評価されません。これは、条件の1つが他の条件よりも集中する場合に特に役立ちます。

Orが適切な例(両方の条件が評価されます):

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

彼らがどのように評価されるかは本当に関係ありません

次のAndAlsoは、2番目の条件が失敗する可能性があるため便利です。

If Not SomeObject Is Nothing AndAlso CheckObjectExistsInDatabase(SomeObject) Then

これにより、最初の条件でオブジェクトが設定されているかどうかを確認し、設定されている場合にのみデータベース(または他のタスク)を確認できます。これが単純なAndキーワードだった場合、両方が評価されます。

4
davidsleeps

@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
2
dbasnett