Web Design that taps into the haromny and vision of your dreams.

Flow Control and Control Structures in C#

By on in Coding

1,220 words, estimated reading time 6 minutes.

Introduction to Programming with C# Series
  1. Introduction to Programming with C# 7
  2. C# Programming Fundamentals
  3. Introduction to Object-Oriented Programming
  4. C# Object-Oriented Programming Part 2
  5. Flow Control and Control Structures in C#
  6. C# Data Types, Variables and Casting
  7. C# Collection Types (Array, List, Dictionary, Hash Table)
  8. C# Operators
  9. Using Data in C# 7 with ADO.Net & Entity Framework
  10. LINQ: .NET Language Integrated Query
  11. Error and Exception Handling in C#
  12. Advanced C# Programming Topics
  13. Reflection in C#
  14. What Are ASP.Net Webforms
  15. Introduction to ASP.Net MVC
  16. Windows Application Development
  17. Assemblies in C#
  18. Working with Resources Files, Culture & Regions
  19. Regular Expressions in C#
  20. Introduction to XML with C#
  21. Complete Guide to File Handling in C#

Conditional statements allow different sections of code, or actions, to be executed depending on a condition being met. We will also look at how to repeat tasks multiple times.

Conditional Statements in C#

Conditions can be used to validate user input, display certain data depending on the date or day of the week, or any one of thousands of conditions.

If...Else

The most commonly used conditional statement is the If...Else block, in which a statement is evaluated to true or false and depending on the result, a different section of code is executed.

In this sample, the statement checks if the condition is true if it is it executes the first block of code. If the condition is false then it executes the second.

Conditions in the if statement must ALWAYS evaluate to TRUE or FALSE.

int x = 5;
 
if (x >= 3)
{
  Console.WriteLine("X is greater than or equal to 3.");
}
else
{
  Console.WriteLine("X is less than 3.");
}

Have a play by changing the value of X and seeing which code block is executed.

If you only have ONE statement to be executed, like our example, you can omit the braces, but if you have more than one statement you will need the braces. This can make the code a little easier to read, but some consider it bad form.

int x = 5;
 
if (x >= 3)
  Console.WriteLine("X is greater than or equal to 3.");
else
  Console.WriteLine("X is less than 3.");

You don't need to have an else statement. If all you want is to output something on Monday for example:

if (dayOfWeek == Monday)
  Console.WriteLine("Today is Monday");

This will write out "Today is Monday" only if dayOfWeek is Monday, otherwise the code is skipped over.

Nested If Statements

If you have multiple scenarios, you can nest if... else statements:

if (dayOfWeek == Monday)
  Console.WriteLine("Today is Monday");
else if (dayOfWeek == Tuesday)
  Console.WriteLine("Today is Tuesday");
else if (dayOfWeek == Wednesday)
  Console.WriteLine("Today is Wednesday");
else if (dayOfWeek == Thursday)
  Console.WriteLine("Today is Thursday");
else if (dayOfWeek == Friday)
  Console.WriteLine("Today is Friday");

This can get a little complicated for many conditions, so a much easier and efficient method would be to use a switch statement.

Switch Statement

In the previous example with the multiple daysOfWeek, by the time Friday is tested the program has executed four if statements which are a very inefficient method. The code is also a little difficult to read and understand, so a much better method would be to use a switch case statement.

The above example can be simplified to this:

switch(dayOfWeek)
{
  case "Monday": 
    Console.WriteLine("Today is Monday");
    break;
  case "Tuesday": 
    Console.WriteLine("Today is Tuesday");
    break;
  case "Wednesday": 
    Console.WriteLine("Today is Wednesday");
    break;
  case "Thursday": 
    Console.WriteLine("Today is Thursday");
    break;
  case "Friday": 
    Console.WriteLine("Today is Friday");
    break;
}

As you can see, this is much easier to read, and there is only one conditional statement that gets executed so the code is more efficient and faster to execute. Each section of code to execute ends with a break keyword. This tells the compiler that the case has ended. Unlike some languages, such as PHP, you cannot "fall through" case blocks if the code exists. You can only fall through when one case directly follows another case statement:

case "Saturday":
  Console.WriteLine("Today is a Weekend"); // This will ERROR!
case "Sunday":
  Console.WriteLine("Today is a Weekend");
  break;
case "Saturday":
case "Sunday":
  Console.WriteLine("Today is a Weekend"); // This is OK!
  break;

Another useful part of the Switch...Case block is that of a default action. If none of the cases specified is met, then the default will be executed.

switch(dayOfWeek)
{
  case "Monday": 
    Console.WriteLine("Today is Monday");
    break;
  case "Tuesday": 
    Console.WriteLine("Today is Tuesday");
    break;
  case "Wednesday": 
    Console.WriteLine("Today is Wednesday");
    break;
  case "Thursday": 
    Console.WriteLine("Today is Thursday");
    break;
  case "Friday": 
    Console.WriteLine("Today is Friday");
    break;
  default:
    Console.WriteLine("This the weekend!!!");
    break;
}

Default must always be the last statement.

C# allows the use of other keywords as well as break to control the flow of the Switch statement. You can use goto, return and throw.

Goto

The use of Goto does not fall within the structured programming methodology and should be avoided at all costs.

Return

The return keyword is used to return a value back to the calling function.

Throw

The throw is used to raise an exception, which will be captured by your Try... Catch block. This will be covered in much more detail in the section about Exception Handling.

Looping and Iteration in C#

When programming, it is often necessary to repeat a task many times. This is a process known as iteration or looping. C# has a number of methods for looping: Do, While, For and Foreach and in this article, we take a look at each of them and how you use them.

The type of iterative loop is governed by how it should perform and what data types are involved. Some loops check the exit condition before they exit the loop, while others guarantee at least one pass.

The While Loop

The simplest loop is the while loop. This is a loop that executes a code block while the condition is true.

int i = 1;
while (i <= 10)
{
  Console.WriteLine($"Loop {i}");
  i++;
}

This will output:

Loop: 1
Loop: 2
Loop: 3
Loop: 4
Loop: 5
Loop: 6
Loop: 7
Loop: 8
Loop: 9
Loop: 10

There is a danger however that you will get caught in an infinite loop.

An infinite loop occurs when the exit condition is never met, an example of which would be if you forgot to increment i within the loop. The exit condition will always be less than 10, so the loop will never exit.

A while loop will check the condition before entering the loop, and if the condition is met the first time there will be no loop.

int i = 12;
while (i <= 10)
{
  Console.WriteLine($"Loop {i}");
  i++;
}

The Do... While Loop

The do while loop is similar to the while loop, except that it does not check the condition until the end of the first iteration. You are guaranteed to have a minimum of one iteration every time.

int i = 1;
do
{
  Console.WriteLine($"Loop {i}");
  i++;
} while (i <= 10);

Again, you must increment the loop counter yourself to avoid being caught in an infinite loop.

The For Loop

The for loop is one of the most common types of loop. It will loop from a starting count to an ending count then stop. For example, you can loop through numbers 1 to 10. The basic format for a for statement is:

for (start value; end condition; increment counter)
{
  // Code to repeat
}

Looping from 1 to 10 as our first example will be coded as follows:

for (int i = 1; i <= 10; i++)
{
  // Code to repeat
}

It looks a bit complicated, so we'll go through each aspect in turn.

  • int i = 1: Declares a variable called i and initiates the value to 1. This is the loop starting value.
  • i<=10: The program will loop as long as i <= 10. Once this condition is no longer met the loop will exit.
  • i++: Increment the value of i by 1 for the next iteration.

You cannot change the value of i within the code to repeat, but you can access its value:

for (int i = 1; i <= 10; i++)
{
  i = 67; // This line will ERROR!
  Console.WriteLine($"Loop {i}");
}

The ending condition does not have to be a fixed value; you can use a function that returns an int. For example, you can loop through all the values in an array (these will be in detail covered later) using the count function to return the number of elements in the array. You can then use the value of i to access the array element.

string[] daysOfWeek = new string[] {
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday"
};
 
for (int i = 0; i < daysOfWeek.Length; i++)
{
    Console.WriteLine($"Day of Week: {daysOfWeek[i]}");
}

Will output:

Day of Week: Monday
Day of Week: Tuesday
Day of Week: Wednesday
Day of Week: Thursday
Day of Week: Friday

Foreach

The for statement has many individual statements that implement the loop mechanism to iterate through the items of an array. It isn't particularly intuitive and it is prone to error, such as forgetting that the array index starts from 0 and the array length starts from 1. A foreach statement is better in terms of readability and is less error-prone, however, there is a slight performance decrease compared with a for loop.

To iterate through the daysOfWeek array from the previous code, the for loop can be replaced with a foreach:

foreach(string Day in daysOfWeek)
{
  Console.WriteLine($"Day: {Day}");
}

It is much easier to understand what is happening in this example. We declare a value Day of type string (must be the same as the array data type) and it automatically gets assigned the value of daysOfWeek. On the next iteration we get the next array item, and so on until the end of the array is reached.

You cannot assign to the value of Day in this example as it is read only, nor can you modify the daysOfWeek collection.

Loop Control

There are two statements that you can use to control the loop from the inside. The first will skip processing the current iteration and continue onto the next. Both of these keywords can be used in a while, for or foreach loop.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 10; i++)
            {
                if (i == 5)
                    continue;
 
                Console.WriteLine(i);
            }
        }
    }
}

This will output:

1
2
3
4
6
7
8
9
10
Press any key to continue . . .

As you can see once the continue statement is reached, no other code in that iteration will run, the loop counter gets incremented and the loop continues.

The other control keyword is break, and this is used to break out of the loop altogether.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 10; i++)
            {
                if (i == 5)
                    break;
 
                Console.WriteLine(i);
            }
        }
    }
}

Will output:

1
2
3
4
Press any key to continue . . .

Recursion

Recursion is the process whereby a method calls itself until an exit condition is met. Very useful, but also very easy to shoot yourself in the foot over and over and over again.

Recursion is used where a method processes items and calls itself repeatedly to process further items it finds. An example would be a directory tree listing. It first scans the root of the C: drive then calls itself for each directory found. If a subdirectory also contains directories another call to itself is made.

Recursion is also used in mathematics and scientific programming, node programming, artificial intelligence and some database applications.

Recursion is a good way of reusing code and processing multiple levels of data, however, it is very easy for the system to run away. You also need to pass data to the method that can get memory intensive. It will also have an impact on performance.

The following code sample illustrates a recursive method for listing a directory structure.

using System;
using System.Threading;
using System.Text;
using System.IO;
 
class Program
{
    static void Main()
    {
        StringBuilder dirList = new StringBuilder();
 
        dirList = directoryListing("c:/Inetpub", "");
        Console.WriteLine(dirList.ToString());
    }
 
    static StringBuilder directoryListing(string path, string indent)
    {
        StringBuilder result = new StringBuilder();
        DirectoryInfo di = new DirectoryInfo(path);
        DirectoryInfo[] directories = di.GetDirectories();
 
        foreach (DirectoryInfo dir in directories)
        {
            result.AppendLine(indent + dir.Name);
 
            // Call the method again on the directories found
            result.Append(directoryListing(dir.FullName, indent + "..").ToString());
        }
        return result;
    }
}

This routine will scan through the directory specified in the Main method, grab all the subdirectories within that directory, add them to the result, and then call itself on each of the subdirectories found. It will recurse until a folder has no subdirectories. Finally, it returns the result back to the line that called the recursive method, until there are no more recursions to be processed. The result is then handed back to the Main method call.

Each time the recursive method is called you need to tell it where to start from, in this case, the folder to look in. In this example, I also use a parameter for the indent level. Each recursion adds two dots to the previous indent level so you can see the directory structure clearer.

It is very easy for a recursive method to run away with itself, an invalid parameter or start point will cause the method to call itself over and over again and never progress. In this case, you will eventually receive a StackOverflowException, which should be handled with a try-catch block on the first call of the method.

Summary and Conclusions

We have seen how to use conditional statements to perform different actions based on whether the condition evaluates to true or false. We also saw how a switch statement can be used where there are multiple if-else statements to improve readability and performance. We have seen the four iterative loops, while, do while, for and foreach, and we have seen how they can be used to repeat an action many times on certain types of data. Finally, we saw how recursion can be used to repeat an action over a directory structure.

Last updated on: Thursday 11th October 2018

 

Comments

Have a question or suggestion? Please leave a comment to start the discussion.

 

Leave a Reply

Please keep in mind that all comments are moderated according to our privacy policy, and all links are nofollow. Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.

Your email address will not be published.