# Branches and Loops — C#/.NET

Source: https://www.skillbyai.com/en/dotnet/c-control

> Write if, switch, for, foreach, while and do loops correctly.

## The familiar control structures

C# has the C-family control structures: `if`/`else`, `switch`, `for`, `while`, `do ... while`, `foreach`, `break`, `continue` and `return`. Conditions must be `bool`; there is no implicit conversion from `int`, so `if (count)` does not compile. A **switch statement** does not allow fall-through between non-empty sections; each section ends with `break`, `return`, `throw` or `goto case`. **`foreach`** works on anything that provides an enumerator (arrays, lists, dictionaries, strings, LINQ queries) and is the default way to walk a collection; you cannot add to or remove from a `List<T>` while iterating it with `foreach`, which throws `InvalidOperationException`. Use `for` when you need the index or to iterate backwards, for example to remove items safely.

## Choosing a loop

Use foreach for whole collections, for when the index matters, while when the end is unknown.

![Three looping arrows of different shapes side by side: a closed circle around items, a counted spiral, and an open loop with a stop sign.](assets/figures/dotnet/section-2-map.svg) — Figure 2.1 — foreach, for and while loops.

## Loops in practice

Removing items while looping is done backwards with `for`, or with `RemoveAll`.

```cs
var scores = new List<int> { 72, 45, 90, 38, 66 };

foreach (var s in scores)
{
    Console.WriteLine(s >= 50 ? $"{s} pass" : $"{s} fail");
}

for (int i = scores.Count - 1; i >= 0; i--)
{
    if (scores[i] < 50) scores.RemoveAt(i);   // safe: index shifts do not affect earlier items
}

// simpler and clearer
scores.RemoveAll(s => s < 50);

int attempts = 0;
while (attempts < 3 && !TryConnect())
{
    attempts++;
}

static bool TryConnect() => Random.Shared.Next(3) == 0;
```

## No accidental fall-through

In C, forgetting `break` silently runs the next case. C# makes that a compile error, but it also means you must stack labels explicitly (`case 'a': case 'e':`) to share a body.

**Quiz:** What happens if you remove an item from a List<T> inside a foreach over that list?

- [ ] It works and skips the removed item
- [ ] The loop restarts from the beginning
- [x] An InvalidOperationException is thrown
- [ ] It compiles to a for loop automatically

*Answer:* An InvalidOperationException is thrown. Modifying a list during foreach invalidates its enumerator, which throws.
