Monday, 19 December 2011

Lesson 5: Methods

In previous lessons of this tutorial, all of our functionality for each program resided in the Main() method. While this was adequate for the simple programs we used to learn earlier concepts, there is a better way to organize your program, using methods. A method helps you separate your code into modules that perform a given task. The objectives of this lesson are as follows:
  • Understand the structure of a method.
  • Know the difference between static and instance methods.
  • Learn to instantiate objects.
  • Learn how to call methods of an instantiated object.
  • Understand the 4 types of parameters.
  • Learn how to use the this reference.

Method Structure

Methods are extremely useful because they allow you to separate your logic into different units. You can pass information to methods, have it perform one or more statements, and retrieve a return value. The capability to pass parameters and return values is optional and depends on what you want the method to do. Here's a description of the syntax required for creating a method:
    attributes modifiers return-type method-name(parameters )

        {

        statements

        }
We defer discussion of attributes and modifiers to a later lesson. The return-type can be any C# type. It can be assigned to a variable for use later in the program. The method name is a unique identifier for what you wish to call a method. To promote understanding of your code, a method name should be meaningful and associated with the task the method performs. Parameters allow you to pass information to and from a method. They are surrounded by parenthesis. Statements within the curly braces carry out the functionality of the method.
Listing 5-1. One Simple Method: OneMethod.cs

using System;

class OneMethod
{
    public static void Main()
    {
        string myChoice;

        OneMethod om =
new OneMethod();

        do
       {
            myChoice = om.getChoice();

            // Make a decision based on the user's choice
            switch(myChoice)
            {
                case "A":
                case "a":
                    Console.WriteLine("You wish to add an address.");
                    break;
                case "D":
                case "d":
                    Console.WriteLine("You wish to delete an address.");
                    break;
                case "M":
                case "m":
                    Console.WriteLine("You wish to modify an address.");
                    break;
                case "V":
                case "v":
                    Console.WriteLine("You wish to view the address list.");
                    break;
                case "Q":
                case "q":
                    Console.WriteLine("Bye.");
                    break;
                default:
                    Console.WriteLine("{0} is not a valid choice", myChoice);
                    break;
            }

            // Pause to allow the user to see the results
            Console.WriteLine();
            Console.Write("press Enter key to continue...");

            Console.ReadLine();
            Console.WriteLine();

        }
while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants to quit
    }

    string
getChoice()
    {
        string myChoice;

        // Print A Menu
        Console.WriteLine("My Address Book\n");

        Console.WriteLine("A - Add New Address");
        Console.WriteLine("D - Delete Address");
        Console.WriteLine("M - Modify Address");
        Console.WriteLine("V - View Addresses");
        Console.WriteLine("Q - Quit\n");

        Console.Write("Choice (A,D,M,V,or Q): ");

        // Retrieve the user's choice
        myChoice = Console.ReadLine();
        Console.WriteLine();

        return
myChoice;
    }
}
The program in Listing 5-1 is similar to the DoLoop program from Lesson 4, except for one difference. Instead of printing the menu and accepting input in the Main() method, this functionality has been moved to a new method called getChoice(). The return type is a string. This string is used in the switch statement in Main(). The method name "getChoice" describes what happens when it is invoked. Since the parentheses are empty, no information will be transferred to the getChoice() method.
Within the method block we first declare the variable myChoice. Although this is the same name and type as the myChoice variable in Main(), they are both unique variables. They are local variables and they are visible only in the block they are declared. In other words, the myChoice in getChoice() knows nothing about the existence of the myChoice in Main(), and vice versa.
The getChoice() method prints a menu to the console and gets the user's input. The return statement sends the data from the myChoice variable back to the caller, Main(), of getChoice(). Notice that the type returned by the return statement must be the same as the return-type in the function declaration. In this case it is a string.
In the Main() method we must instantiate a new OneMethod object before we can use getChoice(). This is because of the way getChoice() is declared. Since we did not specify a static modifier, as for Main(), getChoice() becomes an instance method. The difference between instance methods and static methods is that multiple instances of a class can be created (or instantiated) and each instance has its own separate getChoice() method. However, when a method is static, there are no instances of that method, and you can invoke only that one definition of the static method.
So, as stated, getChoice() is not static and therefore, we must instantiate a new object to use it. This is done with the declaration OneMethod om = new OneMethod(). On the left hand side of the declaration is the object reference om which is of type OneMethod. The distinction of om being a reference is important. It is not an object itself, but it is a variable that can refer (or point ) to an object of type OneMethod. On the right hand side of the declaration is an assignment of a new OneMethod object to the reference om. The keyword new is a C# operator that creates a new instance of an object on the heap. What is happening here is that a new OneMethod instance is being created on the heap and then being assigned to the om reference. Now that we have an instance of the OneMethod class referenced by om, we can manipulate that instance through the om reference.
Methods, fields, and other class members can be accessed, identified, or manipulated through the "." (dot) operator. Since we want to call getChoice(), we do so by using the dot operator through the om reference: om.getChoice(). The program then executes the statements in the getChoice() block and returns. To capture the value getChoice() returns, we use the "=" (assignment) operator. The returned string is placed into Main()'s local myChoice variable. From there, the rest of the program executes as expected, using concepts from earlier lessons.
Listing 5-2. Method Parameters: MethodParams.cs
using System;

class Address
{
    public string name;
    public
string address;
}

class
MethodParams
{
    public static void Main()
    {
        string myChoice;

        MethodParams mp =
new MethodParams();

        do
       {
            // show menu and get input from user
            myChoice = mp.getChoice();

            // Make a decision based on the user's choice
            mp.makeDecision(myChoice);

            // Pause to allow the user to see the results
            Console.Write("press Enter key to continue...");
            Console.ReadLine();
            Console.WriteLine();
        }
while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants to quit
    }

    // show menu and get user's choice
    string getChoice()
    {
        string myChoice;

        // Print A Menu
        Console.WriteLine("My Address Book\n");

        Console.WriteLine("A - Add New Address");
        Console.WriteLine("D - Delete Address");
        Console.WriteLine("M - Modify Address");
        Console.WriteLine("V - View Addresses");
        Console.WriteLine("Q - Quit\n");

        Console.WriteLine("Choice (A,D,M,V,or Q): ");

        // Retrieve the user's choice
        myChoice = Console.ReadLine();

        return
myChoice;
    }

    // make decision
    void makeDecision(string myChoice)
    {
        Address addr =
new Address();

        switch
(myChoice)
        {
            case "A":
            case "a":
                addr.name = "Joe";
                addr.address = "C# Station";
                this.addAddress(ref addr);
                break;
            case "D":
            case "d":
                addr.name = "Robert";
                this.deleteAddress(addr.name);
                break;
            case "M":
            case "m":
                addr.name = "Matt";
                this.modifyAddress(out addr);
                Console.WriteLine("Name is now {0}.", addr.name);
                break;
            case "V":
            case "v":
                this.viewAddresses("Cheryl", "Joe", "Matt", "Robert");
                break;
            case "Q":
            case "q":
                Console.WriteLine("Bye.");
                break;
            default:
                Console.WriteLine("{0} is not a valid choice", myChoice);
                break;
        }
    }

    // insert an address
    void addAddress(ref Address addr)
    {
        Console.WriteLine("Name: {0}, Address: {1} added.", addr.name, addr.address);
    }

    // remove an address
    void deleteAddress(string name)
    {
        Console.WriteLine("You wish to delete {0}'s address.", name);
    }

    // change an address
    void modifyAddress(out Address addr)
    {
        //Console.WriteLine("Name: {0}.", addr.name); // causes error!
        addr = new Address();
        addr.name = "Joe";
        addr.address = "C# Station";
    }

    // show addresses
    void viewAddresses(params string[] names)
    {
        foreach (string name in names)
        {
            Console.WriteLine("Name: {0}", name);
        }
    }
}

Listing 5-2 is a modification of Listing 5-1, modularizing the program and adding more implementation to show parameter passing. There are 4 kinds of parameters a C# method can handle: out, ref, params, and value. To help illustrate usage of parameters, we created an Address class with two string fields.
In Main() we call getChoice() to get the user's input and put that string in the myChoice variable. Then we use myChoice as an argument to makeDecision(). In the declaration of makeDecision() you'll notice its one parameter is declared as a string with the name myChoice. Again, this is a new myChoice, separate from the caller's argument and local only to this method. Since makeDecision()'s myChoice parameter does not have any other modifiers, it is considered a value parameter. The actual value of the argument is copied on the stack. Variables given by value parameters are local and any changes to that local variable do not affect the value of the variable used in the caller's argument.
The switch statement in makeDecision() calls a method for each case. These method calls are different from the ones we used in Main(). Instead of using the mp reference, they use the this keyword. this is a reference to the current object. We know the current object has been instantiated because makeDecision() is not a static method. Therefore, we can use the this reference to call methods within the same instance.
The addAddress() method takes a ref parameter. This means that a reference to the parameter is copied to the method. This reference still refers to the same object on the heap as the original reference used in the caller's argument. This means any changes to the local reference's object also changes the caller reference's object. The code can't change the reference, but it can make changes to the object being referenced. You can think of this as a way to have an input/output parameter.
As you know, methods have return values, but sometimes you'll want to return more than one value from a method. An out parameter allows you to return additional values from a method.
modifyAddress() has an out parameter. out parameters are only passed back to the calling function. Because of definite assignment rules, you cannot use this variable until it has a valid value assigned. The first line in modifyAddress() is commented on purpose to illustrate this point. Uncomment it and compile to see what happens. Once assigned and the program returns, the value of the out parameter will be copied into the caller's argument variable. You must assign a value to an out parameter before your method returns.
A very useful addition to the C# language is the params parameter, which lets you define a method that can accept a variable number of arguments. The params parameter must be a single dimension or jagged array. When calling viewAddresses(), we pass in four string arguments. The number of arguments is variable and will be converted to a string[] automatically. In viewAddresses() we use a foreach loop to print each of these strings. Instead of the list of string arguments, the input could have also been a string array. The params parameter is considered an input only parameter and any changes affect the local copy only.
In summary, you understand the structure of a method. The four types of paramters are value, ref, out, and params. When you wish to use an instance method, you must instantiate its object as opposed to static methods that can be called any time. The this reference refers to its containing object and may be used to refer to its containing object's members, including methods

Lesson 4: Control Statements - Loops

In the last lesson, you learned how to create a simple loop by using the goto statement. I advised you that this is not the best way to perform loops in C#. The information in this lesson will teach you the proper way to execute iterative logic with the various C# looping statements. Its goal is to meet the following objectives:
  • Learn the while loop.
  • Learn the do loop.
  • Learn the for loop.
  • Learn the foreach loop.
  • Complete your knowledge of the break statement.
  • Teach you how to use the continue statement.

The while Loop

A while loop will check a condition and then continues to execute a block of code as long as the condition evaluates to a boolean value of true. Its syntax is as follows: while (<boolean expression>) { <statements> }. The statements can be any valid C# statements. The boolean expression is evaluated before any code in the following block has executed. When the boolean expression evaluates to true, the statements will execute. Once the statements have executed, control returns to the beginning of the while loop to check the boolean expression again.
When the boolean expression evaluates to false, the while loop statements are skipped and execution begins after the closing brace of that block of code. Before entering the loop, ensure that variables evaluated in the loop condition are set to an initial state. During execution, make sure you update variables associated with the boolean expression so that the loop will end when you want it to. Listing 4-1 shows how to implement a while loop.
Listing 4-1. The While Loop: WhileLoop.cs
using System;

class WhileLoop
{
    public static void Main()
    {
        int myInt = 0;

        while (myInt < 10)
        {
            Console.Write("{0} ", myInt);
            myInt++;
        }
        Console.WriteLine();
    }
}
Listing 4-1 shows a simple while loop. It begins with the keyword while, followed by a boolean expression. All control statements use boolean expressions as their condition for entering/continuing the loop. This means that the expression must evaluate to either a true or false value. In this case we are checking the myInt variable to see if it is less than (<) 10. Since myInt was initialized to 0, the boolean expression will return true the first time it is evaluated. When the boolean expression evaluates to true, the block immediately following the boolean expression will be executed.
Within the while block we print the number and a space to the console. Then we increment (++) myInt to the next integer. Once the statements in the while block have executed, the boolean expression is evaluated again. This sequence will continue until the boolean expression evaluates to false. Once the boolean expression is evaluated as false, program control will jump to the first statement following the while block. In this case, we will write the numbers 0 through 9 to the console, exit the while block, and print a new line to the console.

The do Loop

A do loop is similar to the while loop, except that it checks its condition at the end of the loop. This means that the do loop is guaranteed to execute at least one time. On the other hand, a while loop evaluates its boolean expression at the beginning and there is generally no guarantee that the statements inside the loop will be executed, unless you program the code to explicitly do so. One reason you may want to use a do loop instead of a while loop is to present a message or menu such as the one in Listing 4-2 and then retrieve input from a user.
Listing 4-2. The Do Loop: DoLoop.cs

using System; class DoLoop {     public static void Main()     {         string myChoice;         do        {             // Print A Menu             Console.WriteLine("My Address Book\n");             Console.WriteLine("A - Add New Address");             Console.WriteLine("D - Delete Address");             Console.WriteLine("M - Modify Address");             Console.WriteLine("V - View Addresses");             Console.WriteLine("Q - Quit\n");             Console.WriteLine("Choice (A,D,M,V,or Q): ");             // Retrieve the user's choice             myChoice = Console.ReadLine();             // Make a decision based on the user's choice             switch(myChoice)             {                 case "A":                 case "a":                     Console.WriteLine("You wish to add an address.");                     break;                 case "D":                 case "d":                     Console.WriteLine("You wish to delete an address.");                     break;                 case "M":                 case "m":                     Console.WriteLine("You wish to modify an address.");                     break;                 case "V":                 case "v":                     Console.WriteLine("You wish to view the address list.");                     break;                 case "Q":                 case "q":                     Console.WriteLine("Bye.");                     break;                 default:                     Console.WriteLine("{0} is not a valid choice", myChoice);                     break;             }             // Pause to allow the user to see the results             Console.Write("press Enter key to continue...");             Console.ReadLine();             Console.WriteLine();         } while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants to quit     } }
Listing 4-2 shows a do loop in action. The syntax of the do loop is do { <statements> } while (<boolean expression>);. The statements can be any valid C# programming statements you like. The boolean expression is the same as all others we've encountered so far. It returns either true or false.
In the Main method, we declare the variable myChoice of type string. Then we print a series of statements to the console. This is a menu of choices for the user. We must get input from the user, which is in the form of a Console.ReadLine method which returns the user's value into the myChoice variable. We must take the user's input and process it. A very efficient way to do this is with a switch statement. Notice that we've placed matching upper and lower case letters together to obtain the same functionality. This is the only legal way to have automatic fall through between cases. If you were to place any statements between two cases, you would not be able to fall through. Another point is that we used the default: case, which is a very good habit for the reasons stated in Lesson 3: Control Statements - Selection.

The for Loop

A for loop works like a while loop, except that the syntax of the for loop includes initialization and condition modification. for loops are appropriate when you know exactly how many times you want to perform the statements within the loop. The contents within the for loop parentheses hold three sections separated by semicolons (<initializer list>; <boolean expression>; <iterator list>) { <statements> }.
The initializer list is a comma separated list of expressions. These expressions are evaluated only once during the lifetime of the for loop. This is a one-time operation, before loop execution. This section is commonly used to initialize an integer to be used as a counter.
Once the initializer list has been evaluated, the for loop gives control to its second section, the boolean expression. There is only one boolean expression, but it can be as complicated as you like as long as the result evaluates to true or false. The boolean expression is commonly used to verify the status of a counter variable.
When the boolean expression evaluates to true, the statements within the curly braces of the for loop are executed. After executing for loop statements, control moves to the top of loop and executes the iterator list, which is normally used to increment or decrement a counter. The iterator list can contain a comma separated list of statements, but is generally only one statement. Listing 4-3 shows how to implement a for loop. The purpose of the program is to  print only odd numbers less than 10.
Listing 4-3. The For Loop: ForLoop.cs

using System; class ForLoop {     public static void Main()     {         for (int i=0; i < 20; i++)         {             if (i == 10)                 break;             if (i % 2 == 0)                 continue;             Console.Write("{0} ", i);         }         Console.WriteLine();     } }
Normally, for loop statements execute from the opening curly brace to the closing curly brace without interruption. However, in Listing 4-3, we've made a couple exceptions. There are a couple if statements disrupting the flow of control within the for block.
The first if statement checks to see if i is equal to 10. Now you see another use of the break statement. Its behavior is similar to the selection statements, as discussed in Lesson 3: Control Statements - Selection. It simply breaks out of the loop at that point and transfers control to the first statement following the end of the for block.
The second if statement uses the remainder operator to see if i is a multiple of 2. This will evaluate to true when i is divided by 2 with a remainder equal to zero, (0). When true, the continue statement is executed, causing control to skip over the remaining statements in the loop and transfer back to the iterator list. By arranging the statements within a block properly, you can conditionally execute them based upon whatever condition you need.
When program control reaches either a continue statement or end of block, it transfers to the third section within the for loop parentheses, the iterator list. This is a comma separated list of actions that are executed after the statements in the for block have been executed. Listing 4-3 is a typical action, incrementing the counter. Once this is complete, control transfers to the boolean expression for evaluation.
Similar to the while loop, a for loop will continue as long as the boolean expression is true. When the boolean expression becomes false, control is transferred to the first statement following the for block.
For this tutorial, I chose to implement break and continue statements in Listing 4-3 only. However, they may be used in any of the loop statements.

The foreach Loop

A foreach loop is used to iterate through the items in a list. It operates on arrays or collections such as ArrayList, which can be found in the System.Collections namespace. The syntax of a foreach loop is foreach (<type> <iteration variable> in <list>) { <statements> }. The type is the type of item contained in the list. For example, if the type of the list was int[] then the type would be int.
The iteration variable is an identifier that you choose, which could be anything but should be meaningful. For example, if the list contained an array of people's ages, then a meaningful name for item name would be age.
The in keyword is required.
As mentioned earlier, the list could be either an array or a collection. You learned about arrays in Lesson 02: Operators, Types, and Variables. You can also iterate over C# generic collections also, described in Lesson 20: Introduction to Generic Collections.
While iterating through the items of a list with a foreach loop, the list is read-only. This means that you can't modify the iteration variable within a foreach loop. There is a subtlety here; Later, you'll learn how to create custom types, called class and struct, that can contain multiple fields.  You can change the fields of the class or struct, but not the iteration variable for the class or struct itself in a foreach loop.
On each iteration through a foreach loop the list is queried for a new value. As long as the list can return a value, this value will be put into the read-only iteration variable, causing the statements in the foreach block to be executed. When the collection has been fully traversed, control will transfer to the first executable statement following the end of the foreach block. Listing 4-4 demonstrates how to use a foreach loop.
Listing 4-4. The ForEach Loop: ForEachLoop.cs
using System;

class ForEachLoop
{
    public static void Main()
    {
        string[] names = {"Cheryl", "Joe", "Matt", "Robert"};

        foreach
(string person in names)
        {
            Console.WriteLine("{0} ", person);
        }
    }
}
In Listing 4-4, the first thing we've done inside the Main method is declare and initialize the names array with 4 strings. This is the list used in the foreach loop.
In the foreach loop, we've used a string variable, person, as the item name, to hold each element of the names array. As long as there are names in the array that have not been returned, the Console.WriteLine method will print each value of the person variable to the screen.

Summary

Loops allow you to execute a block of statements repeatedly. C# offers several statements to construct loops with, including the while, do, for, and foreach loops. while loops execute a block of statements as long as an expression is true, do loops execute a block of statements at least once and then keep going as long as a condition is true, for loops execute a block of statements a specified amount of times, and foreach loops execute a block of statements for each item in a collection. Normally a block of statements will execute from beginning to end. However, the normal flow of a loop can be changed with the break and continue statements.
So far, the only method you've seen in this tutorial is the Main method, which is the entry point of a C# application. However, you are probably wanting to write larger programs to test your new knowledge. This requires breaking up the code into methods to keep it organized and logical. For this, I invite you to return for Lesson 5: Introduction to Methods, where you can learn new techniques of organizing your code

Lesson 3: Control Statements - Selection

In the last couple of lessons, every program you saw contained a limited amount of sequential steps and then stopped. There were no decisions you could make with the input and the only constraint was to follow straight through to the end. The information in this lesson will help you branch into separate logical sequences based on decisions you make. More specifically, the goals of this lesson are as follows:
  • Learn the if statements.
  • Learn the switch statement.
  • Learn how break is used in switch statements.
  • Understand proper use of the goto statement.

The if Statement

An if statement allows you to take different paths of logic, depending on a given condition. When the condition evaluates to a boolean true, a block of code for that true condition will execute. You have the option of a single if statement, multiple else if statements, and an optional else statement. Listing 3-1 shows how each of these types of if statements work.
Listing 3-1. forms of the if statement: IfSelection.cs

using System; class IfSelect {     public static void Main()     {         string myInput;         int myInt;
        Console.Write("Please enter a number: ");         myInput = Console.ReadLine();         myInt = Int32.Parse(myInput);
        // Single Decision and Action with braces         if (myInt > 0)         {             Console.WriteLine("Your number {0} is greater than zero.", myInt);         }
        // Single Decision and Action without brackets         if (myInt < 0)             Console.WriteLine("Your number {0} is less than zero.", myInt);
        // Either/Or Decision         if (myInt != 0)         {             Console.WriteLine("Your number {0} is not equal to zero.", myInt);         }         else        {             Console.WriteLine("Your number {0} is equal to zero.", myInt);         }
        // Multiple Case Decision         if (myInt < 0 || myInt == 0)         {             Console.WriteLine("Your number {0} is less than or equal to zero.", myInt);         }         else if (myInt > 0 && myInt <= 10)         {             Console.WriteLine("Your number {0} is in the range from 1 to 10.", myInt);         }         else if (myInt > 10 && myInt <= 20)         {             Console.WriteLine("Your number {0} is in the range from 11 to 20.", myInt);         }         else if (myInt > 20 && myInt <= 30)         {             Console.WriteLine("Your number {0} is in the range from 21 to 30.", myInt);         }         else        {             Console.WriteLine("Your number {0} is greater than 30.", myInt);         }     } }
The statements in Listing 3-1 use the same input variable, myInt as a part of their evaluations. This is another way of obtaining interactive input from the user. Here's the pertinent code:
        Console.Write("Please enter a number: ");
        myInput = Console.ReadLine();
        myInt = Int32.Parse(myInput);

We first print the line "Please enter a number: " to the console. The Console.ReadLine() statement causes the program to wait for input from the user, who types a number and then presses Enter. This number is returned in the form of a string into the myInput variable, which is a string type. Since we must evaluate the user's input in the form of an int, myInput must be converted. This is done with the command Int32.Parse(myInput). (Int32 and similar types will be covered in another lesson on advanced types) The result is placed into the myInt variable, which is an int type.
Now that we have a variable in the type we wanted, we will evaluate it with if statements. The first statement is of the form if (boolean expression) { statements }, as shown below:
        // Single Decision and Action with braces
        if (myInt > 0)
        {
            Console.WriteLine("Your number {0} is greater than zero.", myInt);
        }

You must begin with the keyword if. Next is the boolean expression between parenthesis. This boolean expression must evaluate to a true or false value. In this case, we are checking the user's input to see if it is greater than (>) 0. If this expression evaluates to true, we execute the statements within the curly braces. (We refer to the structure with curly braces as a "block") There could be one or more statements within this block. If the boolean expression evaluates to false, we ignore the statements inside the block and continue program execution with the next statement after the block.
Note: In other languages, such as C and C++, conditions can be evaluated where a result of 0 is false and any other number is true. In C#, the condition must evaluate to a boolean value of either true or false. If you need to simulate a numeric condition with C#, you can do so by writing it as (myInt != 0), which means that the expression evaluates to true if myInt is not 0.
The second if statement is much like the first, except it does not have a block, as shown here:
        // Single Decision and Action without braces
        if (myInt < 0)
            Console.WriteLine("Your number {0} is less than zero.", myInt);

If its boolean expression evaluates to true, the first statement after the boolean expression will be executed. When the boolean expression evaluates to false, the first statement after the boolean expression will be skipped and the next program statement will be executed. This form of if statement is adequate when you only have a single statement to execute. If you want to execute two or more statements when the boolean expression evaluates to true, you must enclose them in a block.
Most of the time, you'll want to make an either/or kind of decision. This is called an if/else statement. The third if statement in Listing 3-1 presents this idea, as shown below:
        // Either/Or Decision
        if (myInt != 0)
        {
            Console.WriteLine("Your number {0} is not equal to zero.", myInt);
        }
        else
         {
            Console.WriteLine("Your number {0} is equal to zero.", myInt);
        }

When the boolean expression evaluates to true, the statement(s) in the block immediately following the if statement are executed. However, when the boolean expression evaluates to false, the statements in the block following the else keyword are executed.
When you have multiple expressions to evaluate, you can use the if/else if/else form of the if statement. We show this form in the fourth if statement of Listing 3-1, and repeated below:
        // Multiple Case Decision
        if (myInt < 0 || myInt == 0)
        {
            Console.WriteLine("Your number {0} is less than or equal to zero.", myInt);
        }
        else if (myInt > 0 && myInt <= 10)
        {
            Console.WriteLine("Your number {0} is in the range from 1 to 10.", myInt);
        }
        else if (myInt > 10 && myInt <= 20)
        {
            Console.WriteLine("Your number {0} is in the range from 11 to 20.", myInt);
        }
        else if (myInt > 20 && myInt <= 30)
        {
            Console.WriteLine("Your number {0} is in the range from 21 to 30.", myInt);
        }
        else
         {
            Console.WriteLine("Your number {0} is greater than 30.", myInt);
        }

This example begins with the if keyword, again executing the following block if the boolean expression evaluates to true. However, this time you can evaluate multiple subsequent conditions with the else if keyword combination. the else if statement also takes a boolean expression, just like the if statement. The rules are the same, when the boolean expression for the else if statement evaluates to true, the block immediately following the boolean expression is executed. When none of the other if or else if boolean expressions evaluate to true, the block following the else keyword will be executed. Only one section of an if/else if/else statement will be executed.
One difference in the last statement from the others is the boolean expressions. The boolean expression, (myInt < 0 || myInt == 0), contains the conditional OR (||) operator. In both the regular OR (|) operator and the conditional OR (||) operator, the boolean expression will evaluate to true if either of the two sub-expressions on either side of the operator evaluate to true. The primary difference between the two OR forms are that the regular OR operator will evaluate both sub-expressions every time. However, the conditional OR will evaluate the second sub-expression only if the first sub-expression evaluates to false.
The boolean expression, (myInt > 0 && myInt <= 10), contains the conditional AND operator.  Both the regular AND (&) operator and the conditional AND (&&) operator will return true when both of the sub-expressions on either side of the operator evaluate to true.  The difference between the two is that the regular AND operator will evaluate both expressions every time. However, the conditional AND operator will evaluate the second sub-expression only when the first sub-expression evaluates to true.
The conditional operators (&& and ||) are commonly called short-circuit operators because they do not always evaluate the entire expression. Thus, they are also used to produce more efficient code by ignoring unnecessary logic.

The switch Statement

Another form of selection statement is the switch statement, which executes a set of logic depending on the value of a given parameter. The types of the values a switch statement operates on can be booleans, enums, integral types, and strings. Lesson 2: Operators, Types, and Variables discussed the bool type, integral types and strings and Lesson 17: Enums will teach you what an enum type is. Listing 3-2 shows how to use the switch statement with both int and string types.
Listing 3-2. Switch Statements: SwitchSelection.cs
using System;

class SwitchSelect
{
    public static void Main()
    {
        string myInput;
        int myInt;

        begin:

        Console.Write("Please enter a number between 1 and 3: ");
        myInput = Console.ReadLine();
        myInt = Int32.Parse(myInput);

        // switch with integer type
        switch (myInt)
        {
            case 1:
                Console.WriteLine("Your number is {0}.", myInt);
                break;
            case 2:
                Console.WriteLine("Your number is {0}.", myInt);
                break;
            case 3:
                Console.WriteLine("Your number is {0}.", myInt);
                break;
            default:
                Console.WriteLine("Your number {0} is not between 1 and 3.", myInt);
                break;
        }

        decide:

        Console.Write("Type \"continue\" to go on or \"quit\" to stop: ");
        myInput = Console.ReadLine();

        // switch with string type
        switch (myInput)
        {
            case "continue":
                goto begin;
            case "quit":
                Console.WriteLine("Bye.");
                break;
            default:
                Console.WriteLine("Your input {0} is incorrect.", myInput);
                goto decide;
        }
    }
}
Note: Listing 3-2 will throw an exception if you enter any value other than an int. i.e. the letter 'a' would be an error. You can visit Lesson 15: Introduction to Exception Handling to learn more about how to anticipate and handle these type of problems.
Listing 3-2 shows a couple of switch statements. The switch statement begins with the switch keyword followed by the switch expression. In the first switch statement in listing 3-2, the switch expression evaluates to an int type, as follows:
        // switch with integer type
        switch (myInt)
        {
            case 1:
                Console.WriteLine("Your number is {0}.", myInt);
                break;
            case 2:
                Console.WriteLine("Your number is {0}.", myInt);
                break;
            case 3:
                Console.WriteLine("Your number is {0}.", myInt);
                break;
            default:
                Console.WriteLine("Your number {0} is not between 1 and 3.", myInt);
                break;
        }

The switch block follows the switch expression, where one or more choices are evaluated for a possible match with the switch expression. Each choice is labeled with the case keyword, followed by an example that is of the same type as the switch expression and followed by a colon (:). In the example we have case 1:, case 2:, and case 3:. When the result evaluated in the switch expression matches one of these choices, the statements immediately following the matching choice are executed, up to and including a branching statement, which could be either a break, continue, goto , return, or throw statement. table 3-1 summarizes the branching statements.
Table 3-1. C# Branching Statements
Branching statement Description
break Leaves the switch block
continue Leaves the switch block, skips remaining logic in enclosing loop, and goes back to loop condition to determine if loop should be executed again from the beginning. Works only if switch statement is in a loop as described in Lesson 04: Control Statements - Loops.
goto Leaves the switch block and jumps directly to a label of the form "<labelname>:"
return Leaves the current method. Methods are described in more detail in Lesson 05: Methods.
throw Throws an exception, as discussed in Lesson 15: Introduction to Exception Handling.
You may also include a default choice following all other choices. If none of the other choices match, then the default choice is taken and its statements are executed. Although use of the default label is optional, I highly recommend that you always include it. This will help catch unforeseen circumstances and make your programs more reliable.
Each case label must end with a branching statement, as described in table 3-1, which is normally the break statement. The break statement will cause the program to exit the switch statement and begin execution with the next statement after the switch block. There are two exceptions to this: adjacent case statements with no code in between or using a goto statement. Here's an example that shows how to combine case statements:
        switch (myInt)
        {
            case 1:
            case 2:
            case 3:
                Console.WriteLine("Your number is {0}.", myInt);
                break;
            default:
                Console.WriteLine("Your number {0} is not between 1 and 3.", myInt);
                break;
        }

By placing case statements together, with no code in-between, you create a single case for multiple values. A case without any code will automatically fall through to the next case. The example above shows how the three cases for myInt equal to 1, 2, or 3, where case 1 and case 2 will fall through and execute code for case 3.
A case statement can only be an exact match and you can't use logical conditions. If you need to use logical conditions, you can use an if/else if/else statement.
Another way to control the flow of logic in a switch statement is by using the goto statement. You can either jump to another case statement, or jump out of the switch statement. The second switch statement in Listing 3-2 shows the use of the goto statement, as shown below:
        // switch with string type
        switch (myInput)
        {
            case "continue":
                goto begin;
            case "quit":
                Console.WriteLine("Bye.");
                break;
            default:
                Console.WriteLine("Your input {0} is incorrect.", myInput);
                goto decide;
        }

Note: in the current example, "continue", is a case of the switch statement -- not the keyword.
The goto statement causes program execution to jump to the label following the goto keyword. During execution, if the user types in "continue", the switch statement matches this input (a string type) with the case "continue": label and executes the "goto begin:" instruction. The program will then leave the switch statement and start executing the first program statement following the begin: label. This is effectively a loop, allowing you to execute the same code multiple times. The loop will end when the user types the string "quit". This will be evaluated with the case "quit": choice, which will print "Bye." to the console, break out of the switch statement and end the program.
Warning: You should not create loops like this. It is *bad* programming style. The only reason it is here is because I wanted to show you the syntax of the goto statement. Instead, use one of the structured looping statements, described in Lesson 04: Control Statements - Loops.
When neither the "continue" nor "quit" strings are entered, the "default:" case will be entered. It will print an error message to the console and then execute the goto decide: command. This will cause program execution to jump to the first statement following the decide: label, which will ask the user if they want to continue or quit. This is effectively another loop.
Clearly, the goto statement is powerful and can, under controlled circumstances, be useful. However, I must caution you strongly on its use. The goto statement has great potential for misuse. You could possibly create a very difficult program to debug and maintain. Imagine the spaghetti code that could be created by random goto statements throughout a program. In the next lesson, I'll show you a better way to create loops in your program.

Summary

The if statement can be written in multiple ways to implement different branches of logic. The switch statement allows a choice among a set of bool, enum, integral, or string types. You use break, continue, goto, return, or throw statements to leave a case statement. Be sure to avoid the goto statement in your code unless you have an extremely good reason for using it.
In addition to branching based on a condition, it is useful to be able to execute a block of statements multiple times. A goto statement is not proper or adequate for such logic. Therefore, I invite you to return for Lesson 4: Control Statements - Loops. This will be a continuation of the same topic.