Skip to content

Loops and iteration

↑

Examples are independent C# snippets for modern .NET console projects unless noted otherwise. Class declarations and top-level code can live in Program.cs when top-level statements come first.

Loops repeat work. Choose a for loop when you need an index, foreach when you only need elements, and while when repetition depends on a condition.

A for loop has an initializer, a condition and an iterator. When traversing an array, valid indexes start at 0 and end at Length - 1.

Example.cs
int[] scores = { 12, 19, 25 };
for (int i = 0; i < scores.Length; i++)
Console.WriteLine($"Index {i}: {scores[i]}");

foreach walks through each element without manual index arithmetic. while tests its condition before each iteration, whereas do while always executes the body at least once.

Example.cs
int total = 0;
foreach (int score in new[] { 10, 20, 30 })
total += score;
int countdown = 3;
while (countdown > 0)
countdown--;
Console.WriteLine(total); // 60

break exits the nearest loop; continue skips to the next iteration. Both are useful, but multiple early exits can make control flow harder to follow.

Example.cs
foreach (int value in new[] { -1, 2, 0, 7 })
{
if (value < 0) continue;
if (value == 0) break;
Console.WriteLine(value); // prints 2 only
}

Deep dive: reason about progress and termination

Section titled “Deep dive: reason about progress and termination”

A loop repeats work while a condition holds. For a while loop, identify the initial state, the condition and the change that eventually makes it false. Missing that change creates an infinite loop. In a for loop those three parts are visible in one place, making it a good fit for indexed iteration over a known range.

Program.cs
int[] scores = { 10, 20, 30 };
int total = 0;
for (int i = 0; i < scores.Length; i++)
{
total += scores[i];
}
Console.WriteLine(total); // 60

The invariant is 0 <= i < scores.Length while indexing. The condition excludes scores.Length because the largest valid index is one less than the array length. An off-by-one error is common when the loop uses <= instead of <.

Use for when you need the index or custom stepping, foreach when you simply read each value, and while for a condition-driven process with an unknown number of repetitions. do ... while executes its body at least once. In foreach, do not expect to be able to replace the collection’s enumeration variable, and do not change a normal List<T> while iterating with its enumerator.

break leaves the nearest loop; continue skips to its next iteration. A method-level return ends the method entirely. These are useful when they make the exit rule obvious, but several nested exits can hide what data has and has not been processed.

Traversing n values once is typically O(n) time. Two nested loops that both traverse the whole input often require O(n²) operations. This matters for large collections and Unity per-frame code. Optimize the algorithm before using micro-optimizations; avoid unnecessarily allocating temporary collections on every frame.

Choose foreach for straightforward collection traversal; use for when the index itself matters.

Always ensure a while loop can terminate; avoid modifying a collection while iterating it with foreach.

Sum every positive value in an array while ignoring negative values.

Reveal a solution

foreach (int n in numbers) { if (n < 0) continue; sum += n; }.