C# Programming/Control

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Conditional, iteration, jump, and exception handling statements control a program's flow of execution.

A conditional statement can decide something using keywords such as if, switch.

An iteration statement can create a loop using keywords such as do, while, for, foreach, and in.

A jump statement can be used to transfer program control using keywords such as break, continue, return, and yield.

Conditional statements[edit | edit source]

A conditional statement decides whether to execute code based on conditions. The if statement and the switch statement are the two types of conditional statements in C#.

if statement[edit | edit source]

As with most of C#, the if statement has the same syntax as in C, C++, and Java. Thus, it is written in the following form:

if (condition)
{
  // Do something
} 
else
{
  // Do something else
}

The if statement evaluates its condition expression to determine whether to execute the if-body. Optionally, an else clause can immediately follow the if body, providing code to execute when the condition is false. Making the else-body another if statement creates the common cascade of if, else if, else if, else if, else statements:

using System;

public class IfStatementSample
{
    public void IfMyNumberIs()
    {
        int myNumber = 5;

        if ( myNumber == 4 )
            Console.WriteLine("This will not be shown because myNumber is not 4.");
        else if( myNumber < 0 )
        {
            Console.WriteLine("This will not be shown because myNumber is not negative.");
        }
        else if( myNumber % 2 == 0 )
            Console.WriteLine("This will not be shown because myNumber is not even.");
        else
        {
            Console.WriteLine("myNumber does not match the coded conditions, so this sentence will be shown!");
        }
    }
}

switch statement[edit | edit source]

The switch statement is similar to the statement from C, C++ and Java.

Unlike C, each case statement must finish with a jump statement (that can be break or goto or return). In other words, C# does not support "fall through" from one case statement to the next (thereby eliminating a common source of unexpected behaviour in C programs). However "stacking" of cases is allowed, as in the example below. If goto is used, it may refer to a case label or the default case (e.g. goto case 0 or goto default).

The default label is optional. If no default case is defined, then the default behaviour is to do nothing.

A simple example:

switch (nCPU)
{
    case 0:
        Console.WriteLine("You don't have a CPU! :-)");
        break;
    case 1:
        Console.WriteLine("Single processor computer");
        break;
    case 2:
        Console.WriteLine("Dual processor computer");
        break;
        // Stacked cases
    case 3:
        // falls through
    case 4:
        // falls through
    case 5:
        // falls through
    case 6:
        // falls through
    case 7:
        // falls through
    case 8:
        Console.WriteLine("A multi processor computer");
        break;
    default:
        Console.WriteLine("A seriously parallel computer");
        break;
}

A nice improvement over the C switch statement is that the switch variable can be a string. For example:

switch (aircraftIdent)
{
    case "C-FESO":
        Console.WriteLine("Rans S6S Coyote");
        break;
    case "C-GJIS":
        Console.WriteLine("Rans S12XL Airaile");
        break;
    default:
        Console.WriteLine("Unknown aircraft");
        break;
}

Iteration statements[edit | edit source]

An iteration statement creates a loop of code to execute a variable number of times. The for loop, the do loop, the while loop, and the foreach loop are the iteration statements in C#.

do ... while loop[edit | edit source]

The do...while loop likewise has the same syntax as in other languages derived from C. It is written in the following form:

do...while-loop ::= "do" body "while" "(" condition ")"
condition ::= boolean-expression
body ::= statement-or-statement-block

The do...while loop always runs its body once. After its first run, it evaluates its condition to determine whether to run its body again. If the condition is true, the body executes. If the condition evaluates to true again after the body has run, the body executes again. When the condition evaluates to false, the do...while loop ends.

using System;

public class DoWhileLoopSample
{
    public void PrintValuesFromZeroToTen()
    {
        int number = 0;

        do
        {
            Console.WriteLine(number++.ToString());
        } while(number <= 10);
    }
}

The above code writes the integers from 0 to 10 to the console.

for loop[edit | edit source]

The for loop likewise has the same syntax as in other languages derived from C. It is written in the following form:

for-loop ::= "for" "(" initialization ";" condition ";" iteration ")" body
initialization ::= variable-declaration | list-of-statements
condition ::= boolean-expression
iteration ::= list-of-statements
body ::= statement-or-statement-block

The initialization variable declaration or statements are executed the first time through the for loop, typically to declare and initialize an index variable. The condition expression is evaluated before each pass through the body to determine whether to execute the body. It is often used to test an index variable against some limit. If the condition evaluates to true, the body is executed. The iteration statements are executed after each pass through the body, typically to increment or decrement an index variable.

public class ForLoopSample
{
    public void ForFirst100NaturalNumbers()
    {
        for (int i = 0; i < 100; i++)
        {
            System.Console.WriteLine(i.ToString());
        }
    }
}

The above code writes the integers from 0 to 99 to the console.

foreach loop[edit | edit source]

The foreach statement is similar to the for statement in that both allow code to iterate over the items of collections, but the foreach statement lacks an iteration index, so it works even with collections that lack indices altogether. It is written in the following form:

foreach-loop ::= "foreach" "(" variable-declaration "in" enumerable-expression ")" body
body ::= statement-or-statement-block

The enumerable-expression is an expression of a type that implements '''IEnumerable''', so it can be an array or a collection. The variable-declaration declares a variable that will be set to the successive elements of the enumerable-expression for each pass through the body. The foreach loop exits when there are no more elements of the enumerable-expression to assign to the variable of the variable-declaration.

public class ForEachSample
{
    public void DoSomethingForEachItem()
    {
        string[] itemsToWrite = {"Alpha", "Bravo", "Charlie"};

        foreach (string item in itemsToWrite)
        System.Console.WriteLine(item);
    }
}

In the above code, the foreach statement iterates over the elements of the string array to write "Alpha", "Bravo", and "Charlie" to the console.

while loop[edit | edit source]

The while loop has the same syntax as in other languages derived from C. It is written in the following form:

while-loop ::= "while" "(" condition ")" body
condition ::= boolean-expression
body ::= statement-or-statement-block

The while loop evaluates its condition to determine whether to run its body. If the condition is true, the body executes. If the condition then evaluates to true again, the body executes again. When the condition evaluates to false, the while loop ends.

using System;

public class WhileLoopSample
{
    public void RunForAWhile()
    {
        TimeSpan durationToRun = new TimeSpan(0, 0, 30);
        DateTime start = DateTime.Now;

        while (DateTime.Now - start < durationToRun)
        {
            Console.WriteLine("not finished yet");
        }
        Console.WriteLine("finished");
    }
}

Jump statements[edit | edit source]

A jump statement can be used to transfer program control using keywords such as break, continue, return, yield, and throw.

break[edit | edit source]

A break statement is used to exit from a case in a switch statement and also used to exit from for, foreach, while, do .. while loops that will switch the control to the statement immediately after the end of the loop.

using System;

namespace JumpSample
{
    public class Entry
    {
        static void Main(string[] args)
        {
            int i;
 
            for (i = 0; i < 10; i++) // see the comparison, i < 10
            {
                if (i >= 3)
                {
                    break; 
                    // Not run over the code, and get out of loop.
                    // Note: The rest of code will not be executed,
                    //       & it leaves the loop instantly
                }
            }
            // Here check the value of i, it will be 3, not 10.
            Console.WriteLine("The value of OneExternCounter: {0}", i);
        }
    }
}

continue[edit | edit source]

The continue keyword transfers program control just before the end of a loop. The condition for the loop is then checked, and if it is met, the loop performs another iteration.

using System;

namespace JumpSample
{
    public class Entry
    {
        static void Main(string[] args)
        {
            int OneExternCounter = 0;

            for (int i = 0; i < 10; i++)
            {
                if (i >= 5)
                {
                    continue;   // Not run over the code, and return to the beginning 
                                // of the scope as if it had completed the loop
                }
                OneExternCounter += 1;
            }
            // Here check the value of OneExternCounter, it will be 5, not 10.
            Console.WriteLine("The value of OneExternCounter: {0}", OneExternCounter);
        }
    }
}

return[edit | edit source]

The return keyword identifies the return value for the function or method (if any), and transfers control to the end of the function.

namespace JumpSample
{
    public class Entry
    {
        static int Fun()
        {
            int a = 3;
            return a; // the code terminates here from this function
            a = 9;    // here is a block that will not be executed
        }

        static void Main(string[] args)
        {
            int OnNumber = Fun();
            // the value of OnNumber is 3, not 9...
        }
    }
}

yield[edit | edit source]

The yield keyword is used to define an iterator block that produces values for an enumerator. It is typically used within a method implementation of the IEnumerable interface as an easy way to create an iterator. It is written in the following forms:

yield ::= "yield" "return" expression
yield ::= "yield" "break"

The following example shows the usage of the yield keyword inside the method MyCounter. This method defines an iterator block, and will return an enumerator object that generates the value of a counter from zero to stop, incrementing by step for each value generated.

using System;
using System.Collections;

public class YieldSample
{
    public static IEnumerable MyCounter(int stop, int step)
    {
        int i;

        for (i = 0; i < stop; i += step)
        {
            yield return i;
        }
    }

    static void Main()
    {
        foreach (int j in MyCounter(10, 2))
        {
            Console.WriteLine("{0} ", j);
        }
        // Will display 0 2 4 6 8
    }
}

throw[edit | edit source]

The throw keyword throws an exception. If it is located within a try block, it will transfer the control to a catch block that matches the exception - otherwise, it will check if any calling functions are contained within the matching catch block and transfer execution there. If no functions contain a catch block, the program may terminate because of an unhandled exception.

namespace ExceptionSample
{
    public class Warrior
    {
        private string Name { get; set; }

        public Warrior(string name)
        {
            if (name == "Piccolo")
            {
                throw new Exception("Piccolo can't battle!");
            }
        }
    }

    public class Entry
    {
        static void Main(string[] args)
        {
            try
            {
                Warrior a = new Warrior("Goku");
                Warrior b = new Warrior("Vegeta");
                Warrior c = new Warrior("Piccolo"); // exception here!
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

Exceptions and the throw statement are described in greater detail in the Exceptions chapter.