for and foreach Loops
When you know how many times to repeat — or want to visit every item in a collection — for and foreach are the loops to reach for. This lesson covers both, plus nested loops and the rules for break and continue inside them.
The for loop
A for loop puts the three parts of a counting loop on one line: an initialiser, a condition, and an update that runs after each pass.
for (int i = 1; i <= 5; i++) { Console.WriteLine($"Pass {i}"); }
Pass 1 Pass 2 Pass 3 Pass 4 Pass 5
Step by step: int i = 1 runs once; then i <= 5 is checked before every pass; then i++ runs after every pass. The variable i only exists inside the loop.
Counting in other ways
for (int i = 10; i > 0; i -= 3) // count down in threes { Console.Write(i + " "); } Console.WriteLine(); for (int i = 1; i <= 1000; i *= 10) // multiply each time { Console.Write(i + " "); } Console.WriteLine(); for (int lo = 0, hi = 6; lo < hi; lo++, hi--) // two variables { Console.Write($"({lo},{hi}) "); } Console.WriteLine();
10 7 4 1 1 10 100 1000 (0,6) (1,5) (2,4)
Looping over an array by index
Arrays are numbered from 0, so a loop from 0 to Length - 1 visits every element. Use <, not <= — going one too far throws an IndexOutOfRangeException:
string[] planets = ["Mercury", "Venus", "Earth", "Mars"]; for (int i = 0; i < planets.Length; i++) { Console.WriteLine($"{i + 1}. {planets[i]}"); }
1. Mercury 2. Venus 3. Earth 4. Mars
foreach
If you just need each item, foreach is simpler and can't go out of bounds. It works with arrays, lists, strings, dictionaries — anything that can be enumerated:
string[] fruits = ["apple", "banana", "cherry"]; foreach (string fruit in fruits) { Console.WriteLine(fruit.ToUpper()); } int vowels = 0; foreach (char c in "Programming in C#") { if ("aeiouAEIOU".Contains(c)) { vowels++; } } Console.WriteLine($"Vowels: {vowels}");
APPLE BANANA CHERRY Vowels: 4
The loop variable is read-only — you can't assign to it inside the loop:
int[] numbers = [1, 2, 3]; foreach (int n in numbers) { n = n * 2; }
Program.cs(4,5): error CS1656: Cannot assign to 'n' because it is a 'foreach iteration variable'
To change array elements, use a for loop with an index: numbers[i] *= 2;.
Getting the index in foreach
If you need both the item and its position, Index() (from LINQ) pairs each item with its index:
string[] steps = ["Preheat oven", "Mix ingredients", "Bake 25 minutes"]; foreach (var (index, step) in steps.Index()) { Console.WriteLine($"Step {index + 1}: {step}"); }
Step 1: Preheat oven Step 2: Mix ingredients Step 3: Bake 25 minutes
Nested loops
A loop inside a loop runs completely for every pass of the outer loop — handy for grids and tables:
for (int row = 1; row <= 4; row++) { for (int col = 1; col <= 4; col++) { Console.Write($"{row * col,4}"); } Console.WriteLine(); }
1 2 3 4 2 4 6 8 3 6 9 12 4 8 12 16
{row * col,4} right-aligns each number in a 4-character column (lesson 18).
break and continue in nested loops
break and continue affect only the innermost loop they're in. To leave several loops at once, use a flag variable — or put the loops in a method and return (lesson 20):
int[,] grid = { { 4, 8, 15 }, { 16, 23, 42 }, { 7, 9, 11 }, }; int target = 23; bool found = false; for (int r = 0; r < grid.GetLength(0) && !found; r++) { for (int c = 0; c < grid.GetLength(1); c++) { if (grid[r, c] == target) { Console.WriteLine($"Found {target} at row {r}, column {c}"); found = true; break; // leaves only the inner loop; the flag stops the outer one } } }
Found 23 at row 1, column 1
Ranges of numbers
Enumerable.Range(start, count) produces a sequence of numbers you can loop over with foreach or process with LINQ (lesson 49):
foreach (int n in Enumerable.Range(1, 5)) { Console.Write(n * n + " "); } Console.WriteLine(); Console.WriteLine(Enumerable.Range(1, 100).Sum());
1 4 9 16 25 5050
Choosing a loop
| Loop | Use it when |
|---|---|
foreach | You want every item of a collection. Your default choice. |
for | You need the index, a fixed count, a custom step, or to modify array elements. |
while | You repeat until a condition changes and don't know how many passes it'll take. |
do-while | The body must run at least once. |
Try it yourself
Print a right-angled triangle of stars. Then change it to count down, or to print numbers instead of stars.
* ** *** **** ***** -----