Site

Control Flow — C# Execution Control

Tutorial 5.0  •  C# / Learn

5.0 What This Teaches

This tutorial covers how C# controls execution flow:

5.1 if / else if / else

Conditions must be of type bool. C# does not coerce integers to booleans the way C does:
int score = 78;

if (score >= 90)
    Console.WriteLine("A");
else if (score >= 80)
    Console.WriteLine("B");
else if (score >= 70)
    Console.WriteLine("C");
else
    Console.WriteLine("Below C");  // prints: Below C (78 is not >= 80)
Curly braces are optional for single-statement bodies, but always using them avoids bugs when you later add a second statement and forget the braces.

5.2 switch Statement

int day = 3;
switch (day)
{
    case 1:
        Console.WriteLine("Monday");
        break;
    case 2:
        Console.WriteLine("Tuesday");
        break;
    case 3:
    case 4:
        Console.WriteLine("Wednesday or Thursday");
        break;
    default:
        Console.WriteLine("Other day");
        break;
}
Each case must end with break (or return, throw, or goto). Fall-through is only allowed when a case body is completely empty (as with 3 and 4 above).

5.3 switch Expression (C# 8+)

The switch expression produces a value and requires no break statements:
int day = 3;
string name = day switch
{
    1 => "Monday",
    2 => "Tuesday",
    3 => "Wednesday",
    4 => "Thursday",
    5 => "Friday",
    _ => "Weekend"
};
Console.WriteLine(name);  // Wednesday
The underscore _ is the discard pattern - it matches anything not matched above. The compiler warns if the switch is not exhaustive.

5.4 for Loop

for (int i = 0; i < 5; i++)
    Console.Write($"{i} ");   // 0 1 2 3 4

Console.WriteLine();

// Loop variable scoped to the loop body
for (int i = 10; i > 0; i -= 2)
    Console.Write($"{i} ");   // 10 8 6 4 2

5.5 foreach Loop

foreach iterates any type implementing IEnumerable - arrays, lists, strings, and more. Use it when you don't need the index:
string[] fruits = { "apple", "banana", "cherry" };
foreach (string fruit in fruits)
    Console.WriteLine(fruit);

// Also works on strings (iterates chars)
foreach (char c in "hello")
    Console.Write($"{c} ");   // h e l l o

5.6 while and do-while

int n = 1;
while (n < 100)
    n *= 2;
Console.WriteLine(n);   // 128 (first power of 2 >= 100)

// do-while always executes at least once
string input;
do
{
    Console.Write("Enter 'quit' to exit: ");
    input = Console.ReadLine() ?? "";
}
while (input != "quit");

5.7 break and continue

// break exits the loop immediately
for (int i = 0; i < 10; i++)
{
    if (i == 5) break;
    Console.Write($"{i} ");   // 0 1 2 3 4
}

// continue skips the rest of the current iteration
for (int i = 0; i < 10; i++)
{
    if (i % 2 == 0) continue;
    Console.Write($"{i} ");   // 1 3 5 7 9
}

5.8 Ternary Operator

int x = 7;
string label = x % 2 == 0 ? "even" : "odd";
Console.WriteLine(label);   // odd

int abs = x < 0 ? -x : x;  // inline absolute value
The ternary operator is an expression, not a statement - it produces a value. Use it for simple conditional assignments; for complex logic, prefer a full if statement for readability.

5.9 Example - All Together

// Control Flow - fizzbuzz and switch expression demonstration.

for (int i = 1; i <= 20; i++)
{
    string label = (i % 15 == 0) ? "FizzBuzz"
                 : (i % 3 == 0)  ? "Fizz"
                 : (i % 5 == 0)  ? "Buzz"
                 : i.ToString();
    Console.Write($"{label} ");
}
Console.WriteLine();

// Switch expression for season
int month = 8;
string season = month switch
{
    12 or 1 or 2 => "Winter",
    3 or 4 or 5  => "Spring",
    6 or 7 or 8  => "Summer",
    _            => "Autumn"
};
Console.WriteLine($"Month {month} is {season}.");

5.10 Exercise

Exercise
  • Use a for loop to sum all integers from 1 to 100. Print the result.
  • Use foreach on an array of strings; print only strings with more than 5 characters.
  • Write a switch expression that maps a letter grade ("A".."F") to a GPA value (4.0..0.0).

5.11 Common Mistakes

Forgetting break in a switch statement

Unlike C and Java, C# requires an explicit break at the end of each non-empty case. Omitting it is a compile error, not a silent fall-through.

Modifying a collection during foreach

var list = new List<int> { 1, 2, 3 };
foreach (var x in list)
    list.Remove(x);   // InvalidOperationException: collection modified during iteration
Collect items to remove in a separate list first, then remove them after the loop.

Off-by-one in for loops

int[] arr = { 10, 20, 30 };
for (int i = 0; i <= arr.Length; i++)   // <= causes IndexOutOfRangeException on last iteration
    Console.WriteLine(arr[i]);
// Correct: i < arr.Length

5.12 Key Terms

TermMeaning
if / else if / elseConditional branching; condition must be bool
switch statementMulti-branch dispatch on a value; each case needs break
switch expressionC# 8+ expression form returning a value; no break needed
forLoop with initializer, condition, and increment
foreachIterates any IEnumerable; no index needed
whileRepeats while condition is true; checks before each iteration
do-whileLike while but checks after the body; executes at least once
breakExits the enclosing loop or switch immediately
continueSkips the rest of the current loop iteration
ternary (?:)Inline expression: condition ? value_if_true : value_if_false