Chapter 12: Iterating Data - The 'foreach' Loop and Array Traversal
Theoretical Foundations
In the previous chapter, we learned about arrays (Chapter 11). An array is a fixed-size container for variables of the same type. We access these variables using an index, which is just a number representing the position of an item in the list (starting at 0).
For example, if we have an array of integers, we access them like this:
int[] scores = { 100, 95, 80 };
// We access them individually:
Console.WriteLine(scores[0]); // Prints 100
Console.WriteLine(scores[1]); // Prints 95
Console.WriteLine(scores[2]); // Prints 80
While this works, it requires us to manually track the size of the array and manage the index numbers. If we want to process every item in the array, we usually use a for loop (Chapter 9). However, C# provides a specialized loop designed specifically for this task: the foreach loop.
The "Shopping List" Analogy
Imagine you have a physical shopping list on a piece of paper.
- The
forloop approach: To read this list, you might say to yourself: "Look at line 1, read it. Look at line 2, read it. Look at line 3, read it." You are explicitly managing the line numbers (the index). - The
foreachloop approach: You simply pick up the paper and scan your eyes down it. You don't think "line 1, line 2." You just read what is there. You are saying, "For every item in this list, do something."
The foreach loop lets you focus on the data (the items) rather than the mechanics (the indexes).
Syntax and Structure
The foreach loop is designed to be readable. It reads almost like an English sentence.
Allowed Syntax:
Breakdown:
foreach: The keyword that starts the loop.(...): Contains the declaration of how to handle the items.type variableName: This declares a new variable that will hold the current item being looked at during that specific cycle of the loop. Thetypemust match the type of items in the array (or be a type it can be converted to).in: A keyword separating the temporary variable from the source of data.collectionName: The array we want to iterate over.
Example:
using System;
class Program
{
static void Main()
{
// 1. We define an array of strings (Chapter 11)
string[] pets = { "Dog", "Cat", "Parrot" };
// 2. The foreach loop
foreach (string pet in pets)
{
// 'pet' is a temporary variable.
// In the first loop, it is "Dog".
// In the second loop, it is "Cat".
// In the third loop, it is "Parrot".
Console.WriteLine("I have a " + pet);
}
}
}
Output:
How It Works Internally (The "Black Box")
You do not need to write the code for the foreach loop to work, but understanding the logic helps.
When the compiler sees foreach (string pet in pets), it essentially does the following automatically:
- It looks at the array
pets. - It grabs the item at index 0 and puts it into the variable
pet. - It runs the code inside the
{ }. - It grabs the item at index 1 and puts it into
pet. - It runs the code inside the
{ }. - It repeats this until it reaches the end of the array.
Comparison: for vs. foreach
Why learn foreach if we already know for loops (Chapter 9)?
1. The for loop (Manual Control):
You have access to the index number (i).
int[] numbers = { 10, 20, 30 };
for (int i = 0; i < numbers.Length; i++)
{
// We can access the index
Console.WriteLine("Item at index " + i + " is " + numbers[i]);
// We can modify the array
numbers[i] = numbers[i] + 1;
}
2. The foreach loop (Read-Only & Simple):
You do not have access to the index number. You only have the value.
int[] numbers = { 10, 20, 30 };
foreach (int num in numbers)
{
// We CANNOT easily know what index 'num' is at.
// We CANNOT modify the array 'numbers' directly using 'num'.
Console.WriteLine("The value is " + num);
}
Key Rule: The foreach loop is primarily for reading data. It is safer because it prevents you from accidentally accessing an index that doesn't exist (like index 10 in an array of size 3).
Iterating Over Different Types
The foreach loop works on any array type, as long as you declare the correct variable type inside the loop.
Integers:
Doubles:
double[] prices = { 1.99, 2.50, 3.00 };
foreach (double price in prices)
{
Console.WriteLine(price);
}
Booleans:
bool[] flags = { true, false, true };
foreach (bool flag in flags)
{
if (flag == true)
{
Console.WriteLine("Flag is active");
}
}
Nested foreach Loops (Multi-Dimensional Arrays)
In Chapter 11, we touched on multi-dimensional arrays (grids). We can use foreach loops inside other foreach loops to "dig" into the data.
Imagine a grid of integers (like a chessboard).
using System;
class Program
{
static void Main()
{
// A 2x3 grid (2 rows, 3 columns)
int[,] grid = {
{ 1, 2, 3 },
{ 4, 5, 6 }
};
// Outer loop: Iterates over the rows
// In a 2D array, the first item is the 'row' dimension.
// However, 'foreach' doesn't care about dimensions, it just grabs chunks.
// To be strict with allowed concepts, we treat the 2D array as a sequence of rows.
// But to visualize it, we usually use nested loops.
// Let's look at the rows first.
// We need to know how many rows exist. We use the .GetLength(0) method (allowed in Ch 11).
int rows = grid.GetLength(0);
int cols = grid.GetLength(1);
// We will use a standard 'for' loop for the rows because 'foreach' on a 2D array
// returns 1D arrays (which might be confusing for a beginner right now).
// But let's stick to the pure 'foreach' concept where possible.
// Actually, strictly speaking, 'foreach' on a multi-dimensional array iterates linearly.
// But to make it understandable, let's simulate the grid traversal logic using allowed concepts.
Console.WriteLine("--- Reading the Grid ---");
// We know the size of the first dimension (rows)
for (int i = 0; i < grid.GetLength(0); i++)
{
// We know the size of the second dimension (cols)
for (int j = 0; j < grid.GetLength(1); j++)
{
// Accessing specific index
int value = grid[i, j];
Console.Write(value + " ");
}
Console.WriteLine(); // New line after every row
}
}
}
for loops here for the indices, a foreach loop on grid would simply give us {1, 2, 3} then {4, 5, 6} (which are the rows themselves as arrays). For beginners, the nested for loop is often clearer for grids, but foreach is excellent for simple lists.
The "Read-Only" Safety Feature
One of the most important rules of foreach is that it protects the collection.
Inside a foreach loop, the variable (e.g., pet or score) is read-only. You cannot change the value inside the array using that variable.
int[] numbers = { 1, 2, 3 };
foreach (int num in numbers)
{
// This is ILLEGAL. It will cause a compiler error.
// num = num + 1;
// Why? Because 'num' is a copy of the value in the array,
// or a protected reference. Changing 'num' doesn't change 'numbers'.
// However, if the array held objects (later chapters),
// you could modify properties, but for simple types like int, it is forbidden.
}
When to use foreach vs. for
-
Use
foreachwhen:- You want to look at every item in a collection.
- You don't need to know the index number (position).
- You don't need to modify the items in the collection.
- You want cleaner, easier-to-read code.
-
Use
forwhen:- You need to know the position (e.g., "Print the 5th item").
- You need to modify the array items (e.g.,
numbers[i] = 0). - You need to iterate backwards or skip items in a complex pattern.
The foreach loop is a specialized tool for iterating over a collection of data. It abstracts away the complexity of managing index numbers (i++, i < length), allowing you to focus purely on the data itself. It relies on the array having a defined order and size (fixed in Chapter 11), and it ensures safety by preventing modification of the collection structure during iteration.
In AI development, you will often receive data in arrays (e.g., a batch of text inputs, a set of sensor readings). Using foreach allows you to process these inputs one by one cleanly without worrying about the underlying count.
Basic Code Example
Here is a simple, "Hello World" level code example demonstrating the foreach loop for iterating over an array.
using System;
// REAL-WORLD CONTEXT:
// Imagine you are organizing a digital playlist. You have a fixed list of song titles
// stored in an array. You want to display each song title to the user one by one.
// Using a 'foreach' loop is the cleanest way to read through every item in the list.
class Program
{
static void Main()
{
// 1. We declare an array of strings to hold our playlist.
// Arrays are fixed-size collections (Chapter 11).
string[] playlist = { "Bohemian Rhapsody", "Stairway to Heaven", "Hotel California" };
// 2. We use the 'foreach' loop to iterate over the array.
// This loop automatically visits every element from start to finish.
// 'song' is a temporary variable that holds the current element.
foreach (string song in playlist)
{
// 3. Inside the loop body, we print the current song to the console.
Console.WriteLine($"Now playing: {song}");
}
}
}
How the Code Works: Step-by-Step
-
Array Initialization: We create a string array named
playlist. It contains three specific song titles. The array knows its size (3) immediately upon creation. -
The
foreachStatement: The lineforeach (string song in playlist)acts as a command: "For every item insideplaylist, assign that item to the variablesong, and execute the code block below."string song: This defines the type and name of the variable that will hold the current item. Sinceplaylistholds strings,songmust be astring.in playlist: This specifies the collection we want to read.
-
Execution Flow:
- Iteration 1: The loop picks the first item ("Bohemian Rhapsody").
songbecomes "Bohemian Rhapsody". TheConsole.WriteLineexecutes. - Iteration 2: The loop picks the second item ("Stairway to Heaven").
songbecomes "Stairway to Heaven". TheConsole.WriteLineexecutes. - Iteration 3: The loop picks the third item ("Hotel California").
songbecomes "Hotel California". TheConsole.WriteLineexecutes.
- Iteration 1: The loop picks the first item ("Bohemian Rhapsody").
-
Termination: Once the loop processes the last item in the array, it automatically stops. You do not need to manage an index counter or check boundaries manually.
Visualizing the Loop Execution
The following diagram illustrates how the foreach loop moves through the array indices sequentially.
Common Pitfalls
Attempting to Modify the Array Inside the Loop A common mistake beginners make is trying to change the value of the array element using the iteration variable.
// ❌ INCORRECT CODE - This will not compile
foreach (string song in playlist)
{
// Error: Cannot assign to 'song' because it is a 'foreach iteration variable'
song = "New Song";
}
Why this happens:
The variable song is a read-only copy of the current element. It exists only for the duration of that specific iteration to let you read the value. You cannot use foreach to modify the contents of the array directly. If you need to modify array elements, you must use a standard for loop (Chapter 9) using an index (e.g., playlist[i] = "New Song";).
The chapter continues with advanced code, exercises and solutions with analysis, you can find them on the ebook on Leanpub.com or Amazon
Code License: All code examples are released under the MIT License. Github repo.
Content Copyright: Copyright © 2026 Edgar Milvus | Privacy & Cookie Policy. All rights reserved.
All textual explanations, original diagrams, and illustrations are the intellectual property of the author. To support the maintenance of this site via AdSense, please read this content exclusively online. Copying, redistribution, or reproduction is strictly prohibited.