Cags Posted January 10, 2006 Posted January 10, 2006 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 I've always considered 'And' to be the exact equivalent in VB but it would seem that might not be the case. I guess really I'm just looking for confirmation either way. Quote Anybody looking for a graduate programmer (Midlands, England)?
mskeel Posted January 10, 2006 Posted January 10, 2006 does this mean it will evaluate both expressions before checking if they are both true? Yes. Screwy, isn't 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++: if (someObj != null && someObj.IsAGoodObject) { ///blah blah blah } This code will do the same in VB. which is what I expect to happen: 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 didn't know about the AndAlso operator, becuase that behaviour should be the default. Why wouldn't 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. It's the same case there. The entire expression will be evaluated using just Or's. With OrElse execution will stop at the first True statement. Quote
JamieB Posted January 10, 2006 Posted January 10, 2006 Correctamundo! I was horrified when I discovered that VB was evaluating all expressions in my carefully constructed "if" statements. Quote
Administrators PlausiblyDamp Posted January 10, 2006 Administrators Posted January 10, 2006 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. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Cags Posted January 10, 2006 Author Posted January 10, 2006 Just as I thought, how very strange. I can't see any reason why you would need all expressions evaluated if the first one is false. It's 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 I'd have realised that VB was evaluating all of the expressions I'd have probably changed it to... If expression1 then if expression2 then 'do something end if else end if But now I guess I'll know to use AndAlso. I'm also glad you've pointed out the OrElse statement because I'm sure that could have caused some annoyance in the future. Quote Anybody looking for a graduate programmer (Midlands, England)?
VagabondSW Posted January 10, 2006 Posted January 10, 2006 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. 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: 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. Quote "Never ascribe to malice that which can adequately be explained by incompetence." -- Napolean Bonaparte
Leaders snarfblam Posted January 10, 2006 Leaders Posted January 10, 2006 C# and VB both contain short-circuited and non-short-circuited logical operators: AndAlso 'Short-circuited And 'Not short-circuited && // Short-curcuited & // Many people don't 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: 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 shouldn't 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 wouldn't 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. Quote [sIGPIC]e[/sIGPIC]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.