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.

C#
for (int i = 1; i <= 5; i++)
{
    Console.WriteLine($"Pass {i}");
}
Output
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

C#
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();
Output
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:

C#
string[] planets = ["Mercury", "Venus", "Earth", "Mars"];

for (int i = 0; i < planets.Length; i++)
{
    Console.WriteLine($"{i + 1}. {planets[i]}");
}
Output
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:

C#
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}");
Output
APPLE
BANANA
CHERRY
Vowels: 4

The loop variable is read-only — you can't assign to it inside the loop:

C#
int[] numbers = [1, 2, 3];
foreach (int n in numbers)
{
    n = n * 2;
}
Build error
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:

C#
string[] steps = ["Preheat oven", "Mix ingredients", "Bake 25 minutes"];

foreach (var (index, step) in steps.Index())
{
    Console.WriteLine($"Step {index + 1}: {step}");
}
Output
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:

C#
for (int row = 1; row <= 4; row++)
{
    for (int col = 1; col <= 4; col++)
    {
        Console.Write($"{row * col,4}");
    }
    Console.WriteLine();
}
Output
   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):

C#
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
        }
    }
}
Output
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):

C#
foreach (int n in Enumerable.Range(1, 5))
{
    Console.Write(n * n + " ");
}
Console.WriteLine();
Console.WriteLine(Enumerable.Range(1, 100).Sum());
Output
1 4 9 16 25
5050

Choosing a loop

LoopUse it when
foreachYou want every item of a collection. Your default choice.
forYou need the index, a fixed count, a custom step, or to modify array elements.
whileYou repeat until a condition changes and don't know how many passes it'll take.
do-whileThe 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.

Try it yourself · Program.cs
Edit the code, copy it into Program.cs and run it with dotnet run Program.cs (.NET 10 or later). How to set up .NET
Output
*
**
***
****
*****
-----