For and Foreach Loops — Iterating Collections

Loops let you execute the same block of code repeatedly — iterating over a list of items, processing each record in a database result, or building output from a collection. C# has four loop constructs, and the two you will use most often are for (index-based, full counter control) and foreach (clean iteration over any collection). In production ASP.NET Core code, LINQ methods often replace explicit loops for data transformation, but understanding loops is essential for understanding what LINQ does under the hood.

The For Loop

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

// Iterating an array with index
string[] fruits = { "Apple", "Banana", "Cherry" };
for (int i = 0; i < fruits.Length; i++)
    Console.WriteLine($"[{i}] {fruits[i]}");
// [0] Apple
// [1] Banana
// [2] Cherry

// Reverse iteration
for (int i = fruits.Length - 1; i >= 0; i--)
    Console.Write(fruits[i] + " ");   // Cherry Banana Apple

// Step by 2
for (int i = 0; i <= 10; i += 2)
    Console.Write($"{i} ");   // 0 2 4 6 8 10

// Nested for — e.g. multiplication table
for (int r = 1; r <= 3; r++)
{
    for (int c = 1; c <= 3; c++)
        Console.Write($"{r * c,4}");
    Console.WriteLine();
}
//    1   2   3
//    2   4   6
//    3   6   9
Note: The for loop’s three parts are all optional. for (;;) is an infinite loop (same as while (true)). You can declare multiple variables in the initialiser: for (int i = 0, j = 10; i < j; i++, j--). The iterator expression can be any valid statement — i++, i += 2, i--. In practice, the standard for (int i = 0; i < n; i++) form covers the vast majority of use cases — stick to it unless you have a specific reason to vary.
Tip: Use for when you need the index (to access neighbouring elements, modify the array in place, or iterate in reverse). Use foreach for everything else — it is more readable, impossible to get an off-by-one error, and works on any IEnumerable<T> including database query results, LINQ projections, and async streams. In ASP.NET Core controller methods, foreach over a list of DTOs to build response models is the idiomatic pattern.
Warning: Never modify a collection while iterating it with foreach — it throws an InvalidOperationException with the message “Collection was modified; enumeration operation may not execute.” If you need to remove items while iterating, iterate backwards with a for loop and remove by index, or use LINQ’s .Where() to build a new filtered collection and assign it back. This is a very common bug for developers new to C#.

The Foreach Loop

// Works on any IEnumerable<T> — arrays, List<T>, LINQ queries, etc.
string[] fruits = { "Apple", "Banana", "Cherry" };

foreach (string fruit in fruits)
    Console.WriteLine(fruit);

// With a List<T>
var numbers = new List<int> { 10, 20, 30, 40, 50 };
int sum = 0;
foreach (int n in numbers)
    sum += n;
Console.WriteLine($"Sum: {sum}");   // Sum: 150

// foreach with index using LINQ
foreach ((int index, string fruit) in fruits.Select((f, i) => (i, f)))
    Console.WriteLine($"[{index}] {fruit}");

// break — exit the loop early
foreach (int n in numbers)
{
    if (n == 30) break;          // stops when n is 30
    Console.Write($"{n} ");      // 10 20
}

// continue — skip the current iteration
foreach (int n in numbers)
{
    if (n % 20 == 0) continue;  // skip multiples of 20
    Console.Write($"{n} ");     // 10 30 50
}

Break and Continue

Keyword Effect Works In
break Exits the current loop immediately for, foreach, while, do-while, switch
continue Skips the rest of the current iteration, goes to next for, foreach, while, do-while
return Exits the entire method (and therefore the loop) Any loop inside a method

Common Mistakes

Mistake 1 — Modifying a collection inside foreach (InvalidOperationException)

❌ Wrong:

var items = new List<int> { 1, 2, 3, 4 };
foreach (int item in items)
    if (item % 2 == 0) items.Remove(item);  // InvalidOperationException!

✅ Correct — use LINQ to build a new collection:

items = items.Where(x => x % 2 != 0).ToList();   // ✓ filters without mutating during iteration

Mistake 2 — Off-by-one in the for loop condition

❌ Wrong — i <= array.Length throws IndexOutOfRangeException on last iteration.

✅ Correct — always use i < array.Length.

🧠 Test Yourself

You need to find the first item in a list that satisfies a condition and stop searching. Which loop construct and keyword achieves this most cleanly?