C# provides standard control structures plus modern switch expressions and pattern matching (C# 8+).

If-Else

  int score = 85;

if (score >= 90)
    Console.WriteLine("Grade: A");
else if (score >= 80)
    Console.WriteLine("Grade: B");
else
    Console.WriteLine("Grade: C or below");

string status = score >= 60 ? "Pass" : "Fail";
  

Switch Statement

  DayOfWeek day = DateTime.Now.DayOfWeek;

switch (day)
{
    case DayOfWeek.Saturday:
    case DayOfWeek.Sunday:
        Console.WriteLine("Weekend");
        break;
    default:
        Console.WriteLine("Weekday");
        break;
}
  

Switch Expressions (C# 8+)

  string Describe(object obj) => obj switch
{
    int n when n < 0 => "Negative integer",
    int n => $"Integer: {n}",
    string s => $"String: {s}",
    null => "Null",
    _ => "Unknown type"
};

Console.WriteLine(Describe(42));
Console.WriteLine(Describe("hello"));
  

Loops

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

// foreach
var fruits = new[] { "apple", "banana", "cherry" };
foreach (var fruit in fruits)
    Console.WriteLine(fruit);

// while
int n = 3;
while (n > 0)
{
    Console.WriteLine(n);
    n--;
}

// do-while
do
{
    Console.WriteLine("At least once");
} while (false);
  

Break and Continue

  for (int i = 0; i < 10; i++)
{
    if (i == 3) continue;
    if (i == 7) break;
    Console.WriteLine(i);
}
  

Pattern matching integrates deeply with switch — use it to replace long chains of if-else type checks.

Range and Index (C# 8+)

  var numbers = new[] { 0, 1, 2, 3, 4, 5 };
var last = numbers[^1];       // 5
var slice = numbers[1..4];    // 1, 2, 3
var tail = numbers[3..];      // 3, 4, 5
  

Guard Pattern with is

  if (input is not string text)
    throw new ArgumentException("Expected string");

if (obj is int { } value && value > 0)
    Console.WriteLine($"Positive: {value}");
  

Iterating Collections

  var inventory = new Dictionary<string, int>
{
    ["apples"] = 50,
    ["oranges"] = 30
};

foreach (var (item, count) in inventory)
    Console.WriteLine($"{item}: {count}");
  

When to Use foreach vs for

  • Use foreach for collections when you do not need the index.
  • Use for when you need the index or must modify the collection during iteration.
  • Use while for unbounded or condition-driven loops.

Common Pitfalls

  • Missing break in switch causes fall-through (unlike some languages, C# requires explicit break unless using switch expressions).
  • Modifying a collection during foreach throws InvalidOperationException — iterate a copy or use a for loop.
  • Off-by-one errors in loop bounds — use < collection.Count not <=.