'And', 'AndAlso', and the '&&' Operators

Cags

Well-known member
Joined
Feb 19, 2004
Messages
690
Location
Melton Mowbray, England
I recently came across the VB operator AndAlso, up untill that point I had no idea such an operator existed. My question is, what exactly is the difference between And and AndAlso (or should that be And and also AndAlso ;)). Logically to me in English terms they mean the same thing, so I looked them up in the VB reference guide. AndAlso is described as a "short-circuiting logical conjunction" which as far as I can discern means the second expression is not evaluated if the first is false. Since And is not described as a "short-circuiting logical conjunction" does this mean it will evaluate both expressions before checking if they are both true?

I know that in c# && is a "short-circuiting logical conjunction" and Ive always considered And to be the exact equivalent in VB but it would seem that might not be the case. I guess really Im just looking for confirmation either way.
 
Cags said:
does this mean it will evaluate both expressions before checking if they are both true?
Yes. Screwy, isnt it? I always use AndAlso because that is the behaviour that I expect. I learned all this the hard way when trying to handle null reference exceptions (which are called core dumps in C, i just realized that...my how polite the compiler has become). Anyway, I ussually do something like this in C/C#/C++:

C#:
if (someObj != null && someObj.IsAGoodObject)
{
   ///blah blah blah
}

This code will do the same in VB. which is what I expect to happen:
Code:
If not someObj is Nothing AndAlso someObj.IsAGoodObject() Then
 Blah blah blah
End if

Executing the VB code with just an "And" will throw an exception if the object is null, which, in C# (and C++ and C) would have been properly avoided. It is extremely agrevating if you didnt know about the AndAlso operator, becuase that behaviour should be the default. Why wouldnt you ditch out as soon as you know that the expression could never be true?

OrElse is the "short-circuiting logical conjunction" version of Or. Its the same case there. The entire expression will be evaluated using just Ors. With OrElse execution will stop at the first True statement.
 
Correctamundo!

I was horrified when I discovered that VB was evaluating all expressions in my carefully constructed "if" statements.
 
If you use the And keyword then both operands are evaluated regardless of the result of the 1st operand, AndAlso will only evaluate the second one if the first is true and therefore the second needs to be evaluated.

We now get the Or and OrElse keywords which provide a similar level of functionality.
 
Just as I thought, how very strange. I cant see any reason why you would need all expressions evaluated if the first one is false. Its hard to believe I originally learnt to program with VB 6, before moving onto c#. Now whenever I look at VB.Net I think how strange it is. If Id have realised that VB was evaluating all of the expressions Id have probably changed it to...
Code:
If expression1 then
   if expression2 then
      do something
   end if
else

end if
But now I guess Ill know to use AndAlso. Im also glad youve pointed out the OrElse statement because Im sure that could have caused some annoyance in the future.
 
Use AndAlso OrElse!

I do programming in both VB.Net and C#. Here is a little blurb I wrote on the subject for some junior programmers on our team.

Visual Basic .NET has the AndAlso and OrElse logical operators, which can perform the same functions as the And and Or operators with one key difference; they exhibit short-circuit behavior.
Code:
Dim dt As DataTable

If Not dt Is Nothing And dt.Rows.Count > 0 Then
   dt.Rows.Clear()
End If
In this example, we declare DataTable dt without the New keyword meaning any attempt to access the properties or methods of DataTable dt will cause the old "Object not set to an instance of an object" NullReferenceException. The previous If statement will throw a NullReferenceException because it uses the And operator to evaluate multiple expressions. The CLR would evaluate the first expression "Not dt Is Nothing" as false because dt is Nothing. However, the And operator directs the CLR to continue evaluating expressions. So, it would also attempt to access the Count property of the Rows collection, which will throw a NullReferenceException because dt is Nothing and therefore has no Rows collection let alone a Count property belonging to a DataRowCollection. The same NullReferenceException would occur if we used the Or operator.

Fortunately, we can short circuit these expression evaluations by using the AndAlso and OrElse operators:
Code:
Dim dt As DataTable

If Not dt Is Nothing AndAlso dt.Rows.Count > 0 Then
   dt.Rows.Clear()
End If
This is the proper way to evaluate expressions and this new If statement will not cause a NullReferenceException. If the first condition of an AndAlso expression evaluates to false, the CLR stops processing conditions and returns False. The OrElse operator works slightly different. If the first condition of an OrElse expression is true, the CLR stops processing conditions and returns True.

The And and Or operators still function as they always have for VB6 compatibility purposes. However, the new AndAlso and OrElse operators bring the short circuit functionality found in other languages to Visual Basic .NET and they are the default logical operators expression evaluations.
 
C# and VB both contain short-circuited and non-short-circuited logical operators:
Code:
AndAlso  Short-circuited
And      Not short-circuited
C#:
&&  // Short-curcuited
&   // Many people dont realize that in addition to
    // being a boolean operator, & doubles as a non-
    // short-circuited logical operator.
There are reasons for using non-short-circuited logical operators, specifically side-effects. Though you see side effects alot more in C++, there are a couple of places they can be seen in VB (and C#). If the two operands of your logical operator are functions that perform certain tasks, you may want to make sure that both tasks are performed, regardless of whether the first one returns a true value.

Take a look at the following code:
Code:
    Dim Number As Integer = 0
    Const NumLimit As Integer = 9
    Dim Character As Char = "A"c
    Const CharacterLimit As Char = "Z"c
 
    Public Sub ExperienceSideEffects()
        While (AdvanceNumber() And AdvanceChar())
            This loop will cause both Number and Character to 
            advance until they both reach their limits
        End While
 
        While (AdvanceNumber() AndAlso AdvanceChar())
            This loop will advance Number until it reaches
            its limit, and only then will it begin to advance
            Character. The loop will terminate when Character
            reaches its limit.
        End While
    End Sub
 
 
     Increments Number and returns true if it reaches its limit
    Private Function AdvanceNumber() As Boolean
        Number += 1
        If Number > NumLimit Then Number = NumLimit Number shouldnt go past limit
        Return (Number = NumLimit)
    End Function
 
     Increments Character and returns true if it reaches its limit
    Private Function AdvanceChar() As Boolean
        Character = ChrW(AscW(Character) + 1)
        If Character > CharacterLimit Then Character = CharacterLimit
        Return (Character = CharacterLimit)
    End Function
The side-effect in the first loop is causing certain values to be incremented, which would not happen with short-circuiting. Using the two different operators will have signifigantly different results. Although the I personally wouldnt write a loop like the first one, and it can be constructed less ambiguously, the first loop will execute in a manner closer to what one would expect than the second loop.
 
Back
Top