Control Flow
Concept
if (condition) { ... } else if (other) { ... } else { ... }. The condition must be a bool — C# does not treat integers as true/false.
Conditions can be nested, but deep nesting hurts readability; use early returns (guard clauses) or switch instead.
switch Statement Compares a value against case labels (constants, patterns, and when guards).
Each section must end with break, return, throw, continue or goto case — no implicit fall-through (error CS0163).
Empty labels may be stacked to share code (case 6: case 7:).
default handles everything else.
C# 8 introduced value switch { pattern => result, ... } — an expression that returns a value, with patterns (>= 1 and <= 6) and the discard _ as the default. The compiler warns if the arms are not exhaustive.
for (init; condition; step) You need an index or a counted loop while (condition)
Repeat while a condition holds (may run 0 times) do { } while (condition); The body must run at least once foreach (var item in collection)
Visit every element of an array or collection break exits the innermost loop (or switch); continue skips to the next iteration; return leaves the whole method.
Why It Matters
Control flow is how programs make decisions — validating input, selecting a gear, processing each CAN frame. Switch expressions and pattern matching (Module 22) make decision logic compact and safe.
Syntax
if (x > 0) { } else { }
switch (x) { case 1: ...; break; default: ...; break; }
var y = x switch { 1 => "one", _ => "other" };
for (int i = 0; i < n; i++) { }
while (cond) { }
do { } while (cond);
foreach (var item in items) { }Example
// if / else if / else, nested conditions
foreach (int temp in new[] { -5, 22, 105 })
{
if (temp < 0)
Console.WriteLine($"{temp}C: freezing");
else if (temp < 90)
{
if (temp > 20)
Console.WriteLine($"{temp}C: warm");
else
Console.WriteLine($"{temp}C: normal");
}
else
Console.WriteLine($"{temp}C: coolant overheat!");
}
// switch statement: no fall-through between sections that contain statements
for (int day = 0; day <= 7; day++)
{
switch (day)
{
case 1:
Console.Write("Mon ");
break;
case 6:
case 7: // empty case labels may be stacked
Console.Write("Weekend ");
break;
case int d when d is >= 2 and <= 5: // case guard
Console.Write($"Weekday{d} ");
break;
default:
Console.Write("Unknown ");
break;
}
}
Console.WriteLine();
// switch expression
string Gear(int g) => g switch
{
-1 => "Reverse",
0 => "Neutral",
>= 1 and <= 6 => $"Gear {g}",
_ => "Invalid"
};
Console.WriteLine(string.Join(", ", new[] { -1, 0, 3, 9 }.Select(G
…Expected Result
-5C: freezing
22C: warm
105C: coolant overheat!
Unknown Mon Weekday2 Weekday3 Weekday4 Weekday5 Weekend Weekend
Reverse, Neutral, Gear 3, Invalid
for: 0 1 2 3 4
while: 3 2 1
do-while ran 1 time(s)
foreach: VCU BMS ABS
odd numbers until 9: 1 3 5 7 9
first negative index: 2Common Mistakes
Forgetting break in a switch section — real compiler error:
Using = instead of == in a condition: if (x = 5) does not compile for int (CS0029), which protects you — but for bool variables if (flag = true) compiles and is a bug.
Off-by-one loop bounds (<= vs <).
Modifying a collection while iterating it with foreach (throws InvalidOperationException).
Infinite while loops whose condition never changes.
int mode = 1;
switch (mode)
{
case 1:
Console.WriteLine("one");
case 2:
Console.WriteLine("two");
break;
}m08_err.cs(4,5): error CS0163: Control cannot fall through from one case label ('case 1:') to anotherBest Practices
Prefer guard clauses (if (invalid) return;) to deep nesting.
Prefer switch expressions for mapping values to results.
Use foreach unless you need the index.
Keep loop bodies small; extract methods.
Interview Relevance
Medium: FizzBuzz-style problems, loop invariants, break vs continue, and switch expressions with patterns.
Practice Questions
Print FizzBuzz for 1–30.
Classify a battery state of charge (0–100) as Critical/Low/Normal/Full with a switch expression.
Sum all even numbers between 1 and 100 with for, then with while.
Find the first duplicate in an array using nested loops.
Read lines until the user types quit using do-while.
Quick Quiz
Q1. (True/False) In C#, control can fall through from one non-empty case section into the next.
Answer: False. It is a compile error (CS0163, verified).
Q2. (Predict the output) int n = 0; do { n++; } while (n < 0); Console.WriteLine(n);
Answer: 1 — the body runs once before the condition is checked (verified).
Q3. (Multiple choice) Which keyword skips the rest of the current iteration? A) break B) continue C) return D) goto Answer: B.
Q4. (Predict the output) 5 switch { < 0 => "neg", 0 => "zero", _ => "pos" } Answer: pos.
Coding Challenge
Write a switch expression that maps a UDS negative response code (0x11, 0x12, 0x13, 0x22, 0x31, 0x33, 0x78) to its name, returning "Unknown NRC 0x.." otherwise.
static string NrcName(byte nrc) => nrc switch
{
0x11 => "serviceNotSupported",
0x12 => "subFunctionNotSupported",
0x13 => "incorrectMessageLengthOrInvalidFormat",
0x22 => "conditionsNotCorrect",
0x31 => "requestOutOfRange",
0x33 => "securityAccessDenied",
0x78 => "requestCorrectlyReceivedResponsePending",
_ => $"Unknown NRC 0x{nrc:X2}"
};
Console.WriteLine(NrcName(0x31));