ASP.NET Basics (part 3): Hard Choices

Learn all about operators and conditional tests in ASP.NET.

Getting Smarter

With a little bit of luck, my previous article on C# left you so excited that you spent the last two weeks eagerly practicing variable names and letting your friends know how much smarter than them you are. And this week, I'm going to help you cement your reputation still further, by giving you a crash course in C#'s conditional statements.

I'll start with a gentle introduction to the comparison operator - the backbone for implementing a conditional statement. Next, I'll be introducing you to the most common conditional statement - the "if" statement. This is followed by the other members of the "if" family, namely the "if-else" and "if-else if-else" conditional statements. Finally, I'll show you how to get to grips with the "switch" conditional statement, the tool of choice when you want to avoid multiple "if-else if-else" branches in your code.

Make sure you're strapped in tight - this is gonna be one hell of a ride!

Apples And Oranges

You'll remember how, in the second part of this tutorial, I used a bunch of mathematical operators to demonstrate how you could perform mathematical operations with numeric variables. But C# doesn't just stop at numeric and string operators - the language also comes with a bunch of comparison operators, whose sole raison d'etre is to evaluate expressions and determine if they are true or false.

The following table should make this clearer.

Assume x=4 and y=10

Operator What It Means Expression Result
== is equal to x == y False
!= is not equal to x != y True
> is greater than x > y False
< is less than x < y True
>= is greater than or equal to x >= y False
<= is less than or equal to x <= y True

Why do you need to know all this? Well, comparison operators come in very useful when building conditional expressions - and conditional expressions come in very useful when adding control routines to your code. Control routines check for the existence of certain conditions, and execute appropriate program code depending on what they find.

The first - and simplest - decision-making routine is the "if" statement, which looks like this:

if (condition)
{
    do this!
}

The "condition" here refers to a conditional expression, which evaluates to either true or false. For example,

if (car brakes fail)
{
    start praying
}

or, to put it in language C# understands:

<%
if (brake == 0)
{
    pray();
}
%>

If the conditional expression evaluates as true, all statements within the curly braces are executed. If the conditional expression evaluates as false, all statements within the curly braces will be ignored, and the lines of code following the "if" block will be executed.

Let's take a quick example:

<script language="c#" runat="server">
void Page_Load()
{
    // temperature
    int temp = 40;

    if (temp > 35)
    {
        message.Text = "Man, it's hot out there!";
    }
}
</script>
<html>
<head><title>Weather Forecast</title></head>
<body>
<asp:label id="message" runat="server" />
</body>
</html>

In this case, a variable named "temp" has been defined, and initialized to the value 40. Next, an "if" statement has been used to check the value of the "temp" variable and display a message if it's over 35. Note my usage of the greater-than (>) conditional operator in the conditional expression.

An important point to note - and one which many novice programmers fall foul of - is the difference between the assignment operator (=) and the equality operator (==). The former is used to assign a value to a variable, while the latter is used to test for equality in a conditional expression.

So

<%
a = 47;
%>

assigns the value 47 to the variable "a", while

<%
a == 47
%>

tests whether the value of "a" is equal to 47.

Do It Or Else...

In addition to the "if" statement, C# also offers the "if-else" statement, which allows you to execute different blocks of code depending on whether the expression is evaluated as true or false.

The structure of an "if-else" statement looks like this:

if (condition)
{
    do this!
}
else
{
    do this!
}

In this case, if the conditional expression evaluates as false, all statements within the curly braces of the "else" block will be executed.

Modifying the example above, we have

<script language="c#" runat="server">
void Page_Load()
{
    // temperature
    int temp = 25;

    if (temp > 35)
    {
        message.Text = "Man, it's hot out there!";
    }
    else
    {
        message.Text = "Well, at least it isn't as hot as it could be!";
    }
}
</script>
<html>
<head><title>Weather Forecast</title></head>
<body>
<asp:label id="message" runat="server" />
</body>
</html>

In this case, if the first past of the construct fails (temperature is not greater than 35), control is transferred to the second part - the "else" statement - and the code within the "else" block is executed instead. You can test both possibilities by adjusting the value of the "temp" variable, and viewing the resulting output in your browser.

Here's the output:

Cookie-Cutter Code

The "if-else" construct certainly offers a smidgen more flexibility than the basic "if" construct, but still limits you to only two possible courses of action. If your script needs to be capable of handling more than two possibilities, you should reach for the "if-else if-else" construct, which is a happy combination of the two constructs you've just been reading about.

if (first condition is true)
{
    do this!
}
else if (second condition is true)
{
    do this!
}
else if (third condition is true)
{
    do this!
}

... and so on ...

else
{
    do this!
}

Take a look at it in action:

<script language="c#" runat="server">
void Page_Load()
{
    // temperature
    int temp = 5;

    if(temp >= 35)
    {
        message.Text = "Man, it's hot out there!";
    }
    else if (temp < 35 && temp >= 10)
    {
        message.Text = "Well, at least it isn't as hot as it could be!";
    }
    else if (temp < 10)
    {
        message.Text = "Man, it's freezing out there!";
    }
    // this is redundant, included for illustrative purposes
    else
    {
        message.Text = "Huh? Somebody screwed up out there!";
    }
}

</script>
<html>
<head><title>Weather Forecast</title></head>
<body>
<asp:label id="message" runat="server" />
</body>
</html>

In this case, depending on the value of the "temp" variable, the appropriate code branch is executed, thereby making it possible to write scripts, which allow for multiple possibilities.

One important point to be noted here: control is transferred to successive "if" branches only if the preceding condition(s) turn out to be false. Or, in English, once a specific conditional expression is satisfied, all subsequent conditional expressions are ignored.

Here's another example, this one using the day of the week to decide which fortune cookie to display.

<script language="c#" runat="server">
void Page_Load()
{
    // get the current day of the week
    DateTime date = System.DateTime.Now;

    string day = date.DayOfWeek.ToString();

    // set the day of the week label
    dayoftheweek.Text = day;

    // check day and set fortune
    if (day == "Monday")
    {
        fortune.Text = "Adam met Eve and turned over a new leaf.";
    }
    else if (day == "Tuesday")
    {
        fortune.Text = "Always go to other people's funerals, otherwise they won't come to yours.";
    }
    else if (day == "Wednesday")
    {
        fortune.Text = "An unbreakable toy is useful for breaking other toys.";
    }
    else if (day == "Thursday")
    {
        fortune.Text = "Be alert - the world needs more lerts.";
    }
        else if (day == "Friday")
    {
        fortune.Text = "Crime doesn't pay, but the hours are good.";
    }
    else
    {
        fortune.Text = "Sorry, closed on the weekend.";
    }
}
</script>
<html>
<head><title>Fortune Cookies, Anyone?</title></head>
<body>
Today is <asp:label id="dayoftheweek" runat="server"  /> and your fortune cookie says <asp:label id="fortune" runat="server" />
</body>
</html>

Here's the output:

A quick note on the following lines of code:

// snip

DateTime date = System.DateTime.Now;
string day = date.DayOfWeek.ToString();

// set the day of the week label
dayoftheweek.Text = day;

// snip

That was an off-the-cuff intro to the DateTime data type in C#. I shall talk about this little data type at a later date (pun intended!). For the moment, just assume that the above code snippet returns the current day of the week.

Three In One

So far, I have demonstrated various mathematical and logical operators. There is one thing common to all these operators - they all require at least two operands (the variables and constants that operators work with). For example, in the following code snippet

<%
c = a + b;
%>

the + operator requires two operands, the variables "a" and "b". Similarly, I have also used two operands with the = operator; the variable "c" and the expression "a + b". All such operators are commonly referred to as "binary" operators.

There are also some operators that require only one operand. Can you think of any? If the auto-increment (++) or auto-decrement (--) operators demonstrated last time came to mind, give yourself a little pat on the back.

<%
a++;
%>

For the record, these operators are also known as "unary" operators.

What does all this have to do with anything? Patience, I'm getting to the point. You might remember how, a few pages ago, I demonstrated the "if-else" conditional statement. C# offers a convenient alternative - the ? conditional operator. The syntax for this operator is as below:

conditional expression ? run this when true : run this when false

Perplexed? It's actually petty simple. When the compiler encounters a statement like the one above, it will evaluate the conditional expression and execute the first statement if the expression evaluates as true, and the second one if false. So the line of code above could also be expanded into the following equivalent:

if (conditional expression)
{
    run this when true
}
else
{
    run this when false
}

In order to better understand the shortcut syntax demonstrated above, here's a rewrite of a previous example using this syntax:

<script language="C#" runat="server">
void Page_Load()
{
    int temp = 45;

    message.Text = (temp > 35) ? "Man, it's hot out there!" : "Well, at least it isn't as hot as it could be!";
}
</script>
<html>
<head><title>Weather Forecast</title></head>
<body>
<asp:label id="message" runat="server" />
</body>
</html>

This operator is also an example of the so-called "ternary" operators, which requires three operands (in this case, the conditional expression and two alternatives).

The primary advantage of using this conditional operator is that the code becomes extremely compact (and, once you're used to it, very easy to read). This is evident from the code listings of the two examples above - the one using the ternary operator is shorter and more concise than the one using the traditional "if-else" syntax.

Friday The 13th

If you take a close look at the "if-else if-else" statement example a few pages back, you'll notice that the conditional expression

temp < 25 && temp >= 10

is slightly different from the ones you've been used to thus far. This is because C# also allows you to combine multiple conditions into a single expression, with the help of an animal called a "logical operator".

The following table should make this clearer.

Assume $delta = 12, $gamma = 12 and $omega = 9

Operator What It Means Example Translation Evaluates To
&& AND $delta == $gamma && $delta > $omega delta equals gamma AND delta is greater than omega True
&& AND $delta == $gamma && $delta < $omega delta equals gamma AND delta is less than omega False
|| OR $delta == $gamma || $delta < $omega delta equals gamma OR delta is less than omega True
|| OR $delta > $gamma || $delta < $omega delta is greater than gamma OR delta is less than omega False
! NOT !$delta delta doesn't exist False

Logical operators are useful because they allow you to logically combine or group different conditional tests together, thereby making it possible to enforce complex business rules in your application logic without too much effort.

So, instead of something as ugly as this

<%
if (day == "Friday")
{
    if (date == "13")
       {
            if (time == "1300 hours")
            {
                fortune = "Brace yourself for some bad luck, it's Friday the 13th";
            }
    }
}

%>

you could have something as elegant as this.

<%

if (day == "Friday" && date == "13" && time == "1300 hours")
{
    fortune = "Brace yourself for some bad luck, it's Friday the 13th";
}

%>

Switching Things Around

Finally, C# rounds out its basket of conditional expressions with the "switch" statement, which offers an alternative method of transferring control from one program block to another. Here's what it looks like:

switch (decision-variable)
{
    case first-condition:
        // do this!
        break;

    case second-condition:
        // do this!
        break;

    case third-condition:
        // do this!
        break;

    // ... and so on...

    default:
        // do this by default!
        break;
}

The "switch" statement can best be demonstrated by rewriting the previous example using "switch" instead of "if-else if-else".

<script language="c#" runat="server">
void Page_Load()
{
    DateTime date = System.DateTime.Now;

    string day = date.DayOfWeek.ToString();

    // set the day of the week label
    dayoftheweek.Text = day;

    switch(day) {
        case "Monday":
            fortune.Text = "Adam met Eve and turned over a new leaf.";
            break;
        case "Tuesday":
            fortune.Text = "Always go to other people's funerals, otherwise they won't come to yours.";
            break;
        case "Wednesday":
            fortune.Text = "An unbreakable toy is useful for breaking other toys.";
            break;
        case "Thursday":
            fortune.Text = "Be alert - the world needs more lerts.";
            break;
        case "Friday":
            fortune.Text = "Crime doesn't pay, but the hours are good.";
            break;
        default:
            fortune.Text = "Sorry, closed on the weekend.";
            break;
    }
}

</script>
<html>
<head><title>Fortune Cookies, Anyone?</title></head>
<body>
Today is <asp:label id="dayoftheweek" runat="server" /> and your fortune cookie says <asp:label id="fortune" runat="server" />
</body>
</html>

Here's the output:

The "switch" statement is followed by a decision variable, which serves as the foundation of the construct. Depending on the value of the decision variable, the various "case" blocks are evaluated and the one matching the decision variable (if available) is executed.

The "switch" statement is followed by a list of "case" blocks, which sets up the different code branches for each possible value of the conditional expression embedded in the "switch" statement. Each block begins with the keyword "case" and a constant value. The "break" keyword is used to break out of the "switch" statement block and move immediately to the lines following it.

It's interesting also to note that the decision variable at the beginning of the "switch" statement can evaluate different data types such as integers, strings, chars or even Booleans (remember these from the previous article?). A "boolean" data type can have only two values, true or false, and are declared using the "bool" keyword. However, if you have only two options available, it makes more sense to use the vanilla "if-else" statement or the ? conditional operator.

You can also evaluate multiple possible values within the same "case" block, simply by clubbing them together. This variant demonstrates, by having one "case" block execute for Mondays, Wednesdays and Fridays and a second "case" block for Tuesdays and Thursdays:

<script language="c#" runat="server">
void Page_Load()
{
    DateTime date = System.DateTime.Now;

    string day = date.DayOfWeek.ToString();

    // set the day of the week label
    dayoftheweek.Text = day;

    switch(day) {
        case "Monday":
        case "Wednesday":
        case "Friday":
            fortune.Text = "Adam met Eve and turned over a new leaf.";
            break;
        case "Tuesday":
        case "Thursday":
            fortune.Text = "Always go to other people's funerals, otherwise they won't come to yours.";
            break;

        default:
            fortune.Text = "Sorry, closed on the weekend";
            break;
    }
}

</script>
<html>
<head><title>Fortune Cookies, Anyone?</title></head>
<body>
Today is <asp:label id="dayoftheweek" runat="server" /> and your fortune cookie says "<asp:label id="fortune" runat="server" />".
</body>
</html>

A number of other keywords are available in the context of a "switch" conditional statement:

  • The "break" keyword is used to break out of the "switch" statement block and move immediately to the lines following it.

  • The "default" keyword is used to execute a default set of statements when the variable passed to "switch" does not satisfy any of the conditions listed within the block.

  • The "continue" keyword can be used to move program execution back to the beginning of the "switch" block (not recommended as you will end up in a messy endless loop if you're careless)

  • The "goto case" construct can be used to jump to another "case" block, while the "goto default" keyword moves program execution to the default "case" block.

Endgame

And that's about it for this article. Over the last few pages, I listed the comparison operators required by conditional statements for branching program execution at run time, gave you a quick overview of the entire family of "if" conditional statements, explained the usage of logical operators to carry out complex decisions in a single expression and wrapped up the article with an explanation of the "switch" conditional statement.

In the next segment of this tutorial, I'll be talking about how you can repeatedly execute the same set of statements using a variety of different loop constructs. C# comes with most of the usual suspects - I'll show you all of them, together with examples and illustrations to get you familiar with the basics, and with the differences between then. Until then, though, you now know enough about C#'s conditional statements to begin writing simple programs - so go practice!

Note: Examples are illustrative only, and are not meant for a production environment. Melonfire provides no warranties or support for the source code described in this article. YMMV!

This article was first published on13 Aug 2003.