Gigi Labs

Saturday, November 30, 2013

VB .NET Basics: Conditionals, Logical Operators and Short-Circuiting

Hello again! :)

Two months ago, I wrote the article "VB .NET Basics: Input and Output", which has recently been gaining a lot of attention. In today's article, we're going to see how we can write conditional statements in VB .NET to let the program take different actions depending on user input. More importantly, we're going to see how to use logical ANDs and ORs in 'If' conditions - something that is likely to catch you off guard if you're coming from some other language.

First, create a new VB .NET Console Application. If you're using SharpDevelop, the project will be created with the following initial code:

We're taking the first character from the user's input (thanks to the Substring() method), converting it to lowercase. That way, whether the user types "Male", "male", or "m126", it's still going to interpret that as being male.

There are a couple of things to note here. First of all, in VB .NET, the = operator (which is the same one used in assigning values to variables) is used for equality comparison. This is quite different from C-like languages which use = for assignment and == for comparison.

Secondly, VB .NET is sensitive to spacing. If you try to put the Then on the next line, like this:

You might be familiar with Else from other languages, but this ElseIf might possibly be new. ElseIf makes its condition (the one checking for female) run only if the initial If returned false - it's the equivalent of writing the following:

...but when you have lots of conditions, it saves you from having to indent indefinitely. ElseIf exists in other languages, but can vary quite a lot between them (e.g. elif in Python, elsif in Perl, or even just else if in the C-like languages).

Of course, when we are checking the same variable over different values, we know we should actually be using a SelectCase statement, which is the equivalent of a switch statement in C# and other C-like languages. We can change the above conditional into a SelectCase as follows:

SelectCase is syntactically quite different from switch statements. In particular, there are no break statements, and CaseElse is the equivalent of the default statement in C-like languages: its statements are executed if none of the earlier cases are matched.

We can now add the following to wait for user input before exiting the application:

Console.ReadLine()

...and then test it (I used Ctrl+F5 to run, instead of debug, the application - this lets you run several instances at the same time):

Now, let's see how to write more interesting conditional statements. To do this, let us first collect the user's age:

So, first we're declaring a message variable, which we'll set in a minute. It's initially set to Nothing, which is equivalent to C# null. Then we're accepting user input, and converting it to a number. We use Integer.TryParse() so that if the conversion fails, it simply returns false and age is not set - this saves us from having to do exception handling as in "C# Basics: Arithmetic and Exceptions".

You might guess that we can logically combine conditional statements using the And and Or statements. Let's try that out:

If converted ThenIf genderStr.Substring(0, 1).ToLower() = "m" And age < 30 Then
message = "You are a young man!"ElseIf genderStr.Substring(0, 1).ToLower() = "m" And age >= 30 Then
message = "You are an old man!"ElseIf genderStr.Substring(0, 1).ToLower() = "f" And age < 30 Then
message = "You are a young lady!"ElseIf genderStr.Substring(0, 1).ToLower() = "f" And age >= 30 Then
message = "You are an old lady!"ElseIf genderStr.Substring(0, 1).ToLower() = "a" Then
message = "Whatever your age, you are an alien."EndIfEndIf

Heh, if you're 30 or over, you're probably shaking your fists. But anyway, since we're dealing with multiple variables, we can't use a SelectCase statement here. Instead, we are checking different combinations of gender and age. Note that I haven't included an Else statement, and this means that if the age conversion fails, then message remains Nothing.

Now, let's show the message. We can handle the case where message is Nothing with another conditional:

Uh oh. What just happened here? Despite the check against Nothing, accessing message.Length still caused a NullReferenceException to be thrown. Why is that? Let's look at our condition again:

If message IsNotNothingAnd message.Length > 0 Then

If message is Nothing, then the first condition resolves to false. At this point we normally expect the second expression to be ignored (which is called short circuiting), but that is not what is happening. The And operator evaluates both expressions, and only then ANDs them together.

In other words, we're using the wrong operator. We need to use AndAlso instead of And, and OrElse instead of Or. AndAlso and OrElse will short circuit (i.e. they won't evaluate both expressions if they don't have to), while And and Or are bitwise operators and mean something different (which we won't go into at this stage). If you're coming from any C-style language such as C#, then you can understand this as follows: AndAlso and OrElse are the equivalents of && and || respectively; while And and Or are the equivalents of & and | respectively.

We can now change our code to use AndAlso instead of And:

If converted ThenIf genderStr.Substring(0, 1).ToLower() = "m" AndAlso age < 30 Then
message = "You are a young man!"ElseIf genderStr.Substring(0, 1).ToLower() = "m" AndAlso age >= 30 Then
message = "You are an old man!"ElseIf genderStr.Substring(0, 1).ToLower() = "f" AndAlso age < 30 Then
message = "You are a young lady!"ElseIf genderStr.Substring(0, 1).ToLower() = "f" AndAlso age >= 30 Then
message = "You are an old lady!"ElseIf genderStr.Substring(0, 1).ToLower() = "a" Then
message = "Whatever your age, you are an alien."EndIfEndIf

And now, this code doesn't raise any exceptions (there is no message written because that's the way the logic works):

Great. In this article, we learned how to use conditional statements in Visual Basic .NET. We started by looking at simple If and Select Case statements, and then discovered how to set up more complex conditions by using Boolean operators to combine simple conditions. The main takeaway from this is that you should always use AndAlso and OrElse in your conditions, not And and Or. This will allow your conditions to short circuit, i.e. if your condition is (A AND B) and A is false, then the condition is false regardless of the value of B, so B is not evaluated. Short circuiting is very important when the second condition is dependent on the first, as we have seen in the above code.