Warum man AndAlso/OrElse in VB.Net verwenden sollte…

VB.Net hat neben den Operatoren And und Or auch die Operatoren AndAlso und OrElse. Diese werden auch als Kurzschluss-Operatoren bezeichnet. Der Unterschied zwischen den Operatoren ist, dass AndAlso und OrElse die Überprüfung abbrechen, sobald das Ergebnis klar ist.

Ich wusste lange nicht, dass es für diesen Zweck extra Operatoren gibt und dachte, dass dieses Verhalten der Standard ist. Und meiner Meinung nach, sollte es der Standard sein. Denn wenn der erste Teil einer And-Bedingung False ist, dann ist das Ergebnis des zweiten Teils irrelevant für das Gesamtergebnis der Bedingung. Warum sollte man also besser immer AndAlso und OrElse verwenden?

Punkt 1: Performance.
Da bereits nach der ersten Bedingung einer If-Bedingung das Ergebnis bekannt sein kann, müssen die anderen Prüfungen nicht mehr durchgeführt werden. Gerade wenn in der Überprüfung beispielsweise Datenbankzugriffe ausgeführt werden, kann viel Performance gespart werden. Aber auch bei kleinen Prüfungen kann Performance gespart werden. Nämlich dann, wenn viele kleinen Überprüfungen nicht mehr ausgeführt werden.

Punkt 2: Subtile Bugs (Unoffensichtliches Verhalten)
Das der zweite Teil eine And-Bedingung auch ausgeführt wird, wenn der erste Teil False war, ist nicht offensichtlich und verleitet zu Fehlern. Deshalb sollte immer AndAlso und OrElse verwendet werden. Ein Beispiel:

Private Function Test(obj As Object) As Boolean
    If obj Is Nothing Then
        Throw New NullReferenceException("Objekt nicht gesetzt.")
    End If
    
    Return True
End Function

Public Sub Main()
    Dim obj As Object = Nothing
    If obj IsNot Nothing And Test(obj) Then
        Console.WriteLine("Okay.")
    End If
End Sub

Die Methode Test wirft eine Exception, wenn die Übergabe Nothing ist. Dies simuliert eine Funktion, welche die Übergabe von Nothing nicht verträgt. Um Fehler direkt abzufangen wird die Variable auf Nothing geprüft und die Methode Test mit der Variablen aufgerufen. Die Ausführung von Main wirft die NullReferenceException, weil der zweite Block ausgeführt wird. Nicht sehr intuitiv. Schreibt man die Main-Methode aber so:

Public Sub Main()
    Dim obj As Object = Nothing
    If obj IsNot Nothing AndAlso Test(obj) Then
        Console.WriteLine("Okay.")
    End If
End Sub

Dann funktioniert es, wie erwartet, indem die Funktion Test nicht ausgeführt wird.

Meine Empfehlung ist also AndAlso und OrElse immer zu verwenden, um solche Bugs zu umgehen und um, wenigstens ein wenig, mehr Performance aus den eigenen Programmen zu holen.