In this article, the latest of our C# in Simple Terms series, we're going to discuss how to control the flow of execution in a C# program. This means we will answer the question, "how does the code know what to do next?"
Our C# programs know what lines of code to execute next through the use of two sets of keywords: the selection statement keywords, and the loop keywords.
The Sample Project
Code Blocks
In C#, a code block is a group of lines of code between curly braces {}
.
{
//Everything between { and } is part of this code block.
}
Both selection statement keywords and loops work with code blocks, though in different ways.
Selection Statement Keywords
These keywords cause "decision points" in C# programs, where the program may or may not execute a code block based on whether a condition or set of conditions is true
.
In C#, this set of keywords consists of if
, else
, switch
, case
, and break
. Let's take a closer look at each of these keywords.
If, Else, If Else
The most basic of the selection statement keywords are if
and else
. We use these keywords to evaluate boolean expressions and direct the program to execute specified lines of code if certain expressions are true.
if (expression) //If this expression evaluates to true...
{
//...Execute this
}
else
{
//Otherwise, execute this
}
We can also use an else if
clause to add more conditions to our evaluation.
decimal money;
decimal orderTotal;
if (money > orderTotal)
{
Console.WriteLine("Thanks for your purchase!");
}
else if (money == orderTotal)
{
Console.WriteLine("Wow! Thanks for having exact change!");
}
else
{
Console.WriteLine("Sorry, you don't have enough money.");
}
An if
statement can be implemented alone. if else
statements and else
statements must follow an if
statement. We can have as many if else
statements as we like in a given set.
We can also nest if
and else
statements to form more complex decisions:
if(expression1)
{
if(expression2)
{
if(expression3) { /*...*/ }
else if(expression4) { /*...*/ }
else ( /*...*/ }
}
else
{
if(expression5) { /*...*/ }
/*...*/ //These lines of code will be executed
//whenever the containing else statement is executed.
}
}
Switch, Case, Break
Sometimes we want to evaluate a given object against a large set of possible values. For these situations, we use the keyword switch
and its related keywords case
and break
.
A switch
statement is used when a single object needs to be evaluated against a large number of potential values. Each of these possible values is identified by using a case
statement. The case
statement can consist of multiple lines of code, and ends when the system encounters the break
keyword.
switch(variable)
{
case value1:
executeThis();
executeThat();
break;
case value2:
executeThisOtherThing();
break;
default:
break;
}
For example, let's imagine we have a company that is sponsoring us for a tournament of some kind. We want to display the company a message, but we need it to be a different message for each level of sponsorship that we offer. We might implement a switch
statement to output the correct message for each sponsorship level:
var sponsorLevel = 2;
switch (sponsorLevel)
{
case 1: //Gold
Console.WriteLine("Thanks for being a gold sponsor!");
break;
case 2: //Silver
Console.WriteLine("Thanks for being a silver sponsor!");
break;
case 3: //Bronze Level 2
case 4: //Bronze Level 1
Console.WriteLine("Thank you for being a bronze sponsor!");
break;
default: //All others
Console.WriteLine("Thank you for sponsoring us!");
Console.WriteLine("Would you like to upgrade to a bronze sponsorship?");
break;
}
Note that we can have multiple case
statements use the same block of code by "stacking" them, like case 3 and case 4 in the example above.
Switch Expression
When we need a switch statement to only produce a concrete value, we can use a switch expression.
For example, let's say we have a set of cards. Each card has a resource type, and a color. The cards with a given resource type always have the same color. If the color and resource type are enumerations (which we will discuss in a later post), we can use a switch expression to give us the color if we have the resource type.
In short, "decision point" statements like if
, else
, and switch
help our applications perform different code depending on specified conditions.
Loops
In C#, loops are code blocks that are executed multiple times. The exact number of times they are executed can differ, or be dependent on a variable, or on a collection of objects.
There are four ways to implement a loop in C#, and they each have a distinct use.
For Loop
A for
loop is a loop that executes once for each value in a given range. The loop must define a variable (commonly named i or j, termed the initializer); a condition where the loop will execute again so long as the condition is true
; and an iterator which defines by how much the initializer will change after every loop.
A common kind of for
loop uses integers and a simple increment.
for(int i = 0; //Initializer
i < 10; //Condition
i++) //Iterator
{
//This code will execute ten times,
//one each for i = 0, i = 1, up to and including i = 9.
}
We can also use increments of values other than 1:
for (int i = 0; i < 10; i += 2) //+= is Increment Assignment Operator
{
//This code will execute five times.
//i = 0, i = 2, i = 4, i = 6, and i = 8
}
for
loops are particularly useful if we know the range of values that we want to loop against in advance.
Foreach Loop
When dealing with collections of objects (such as an array or a List<T>
; both of which will be discussed later in this series), we can use a foreach
loop to iterate over every object in the collection. In this case, the iterator object is of the same type as objects in said collection.
var items = new int[] {4, 5, 6, 7, 8};
foreach(int item in items)
{
Console.WriteLine(item);
}
//Example class
public class Drawing
{
public string Name { get; set; }
}
//Make a collection of Drawings
List<Drawing> drawings = new List<Drawing>()
{
new Drawing()
{
Name = "Test Drawing 1"
},
new Drawing()
{
Name = "Test Drawing 2"
}
};
//Iterate over each drawing in the collection
foreach (Drawing iterator in drawings) //iterator is of type Drawing
{
Console.WriteLine(iterator.Name);
}
Using a foreach
loop to iterate over a collection is the most common scenario for this kind of loop.
While Loop
A while
loop evaluates a condition, and so long as that condition is true, the loop will keep executing.
int myVal = 0;
while(myVal < 1000) //This loop will execute 1000 times...
{
DoSomething();
DoSomethingElse();
myVal = myVal + 1; //...because each time through the loop, we
//increase the value of myVal by 1
}
We must be careful when writing while
loops; it is easy to accidentally create a loop that will never reach the end condition.
int myVal = 5;
while(myVal < 1000)
{
DoSomething();
DoSomethingElse();
//We didn't increment myVal, so this loop will never stop executing!
}
Because a while loop evaluates the condition before entering the loop, if that condition is false
before the loop starts, the loop will not be executed.
Do While Loop
By contrast, a do while
loop will always execute at least once, because the condition is evaluated at the end of the loop.
int myVal = 1;
do
{
DoSomething();
DoSomethingElse();
myVal++;
} while (myVal < 1000);
If you must guarantee that the code in a loop run at least one time, use a do while
loop.
Breaking the Loop
In many situations, we may want to stop executing the loop before the loop reaches its end condition. There are several keywords we can use for these situations.
Break
The break
keyword ends execution of the loop. No further iterations of the loop will execute.
for(int i = 0; i < 10; i++)
{
if(i == 7)
{
break; //Will exit the for loop
}
}
You might have noticed that this keyword was also used in the switch
statement examples above, and its function was similar there.
Continue
The continue
keyword ends execution of the current iteration of the loop, but will restart the loop at the next iteration.
int myVal = 5;
while (myVal < 10)
{
if (myVal == 7)
{
myVal++;
continue; //If i == 7, processing stops here and resumes
//at the top of the loop with the next value 8.
//Console.WriteLine is never called in that case.
}
//The below output will not happen when myVal = 7
Console.WriteLine("The current value of myVal is " + myVal.ToString());
myVal++;
}
Return
The return
keyword, similarly to how it works in methods, will return a value to the calling code. The loop will therefore stop executing.
var emails = GetEmails(); //Method not defined here
foreach(var email in emails)
{
if(email.Sender == "[email protected]")
{
return email; //Loop stops executing
}
}
New Keywords
if
- Specifies a block of code that will executed if a particular condition istrue
.else if
- Specifies a block of code that will executed if a particular condition istrue
. Must be used in tandem with anif
.else
- Specifies a block of code that will be executed if non of the previousif
statements were executed. Must be used with anif
.for
- Specifies a loop that will execute a defined number of times. Must have an initializer, a condition, and an increment.foreach
- Specifies a loop that will execute once for each item in a collection, unless the loop is broken.while
- Specifies a loop that will execute so long as a given condition istrue
.do while
- Specifies a loop that will execute at least once, and then will continue executing as long as the condition istrue
.break
- Stops execution of a loop OR marks the end point of acase
in aswitch
statement.continue
- Stops the current iteration of a loop, and resumes execution at the next iteration.return
- Stops execution of a loop and returns a value to the calling code.
Summary
In C#, we control the flow of execution in our programs by using "decision point" statements such as if
, else
, and switch
and by creating one of the four kinds of loops: for
, foreach
, while
, and do while
. We can also stop or modify execution of those loops using the break
, continue
, and return
keywords.
Woo hoo! We're getting our foundational knowledge down! In the next part of this series, we begin combining our knowledge of control flow and operators to build the next step in our C# program: methods!
Got questions about this post? I'm happy to hear them! Ask questions in the comments below and let's see if we can get you some answers!
Happy Coding!