Skip to content

Control Flow

Control flow statements determine which code runs and how many times. C# offers if/else if/else for branching, switch (statement or expression) for multi-way branching on a single value, and for, foreach, while, and do-while for repetition.

int age = 20;
if (age < 13) Console.WriteLine("child");
else if (age < 20) Console.WriteLine("teenager");
else Console.WriteLine("adult");
// Switch statement
switch (age)
{
case < 13:
Console.WriteLine("child");
break;
case < 20:
Console.WriteLine("teenager");
break;
default:
Console.WriteLine("adult");
break;
}
// Switch expression (C# 8+) -- more concise, returns a value
string category = age switch
{
< 13 => "child",
< 20 => "teenager",
_ => "adult",
};
for (int i = 0; i < 5; i++) Console.WriteLine(i);
foreach (var item in new[] { "a", "b", "c" }) Console.WriteLine(item);

Forgetting break in a traditional switch statement case β€” unlike some languages, C# does not allow implicit fall-through between non-empty cases, so a missing break is actually a compile error, not a silent bug, which is one of C#β€˜s deliberate safety improvements over C/C++/JavaScript.

switch (age)
{
case 18:
Console.WriteLine("just became an adult");
// Error: Control cannot fall through from one case label to another
case 21:
Console.WriteLine("can drink in the US");
break;
}
// Fix: add break, or use goto case for intentional fall-through
  1. Does C#β€˜s traditional switch statement allow implicit fall-through between cases like C or JavaScript does?

    AnswerNo β€” C# requires an explicit break, return, or goto case at the end of every non-empty case; unintentional fall-through is a compile error, not a silent bug.
  2. What’s the difference between a switch statement and a switch expression?

    AnswerA switch statement executes code per case using break; a switch expression (C# 8+) directly evaluates to a value using => arms, often more concise for simple value-selection logic.
  3. What does foreach do that a plain for loop over an index doesn’t?

    AnswerIt iterates directly over the elements of any IEnumerable collection without manual index management, which is both simpler and works for collections that don't support indexed access.