C# Foreach Loop
Introduction
The foreach
loop is one of the most convenient control flow mechanisms in C#, specifically designed for iterating through elements in a collection. Unlike a for
loop where you manually control the iteration, a foreach
loop automatically steps through all items in a collection such as arrays, lists, dictionaries, or any object that implements the IEnumerable
or IEnumerable<T>
interface.
The foreach
loop is particularly helpful for beginners as it simplifies the process of collection traversal by eliminating the need for index management or explicit bounds checking.
Basic Syntax
The syntax of a foreach
loop is straightforward:
foreach (type element in collection)
{
// Code to execute for each element
}
Where:
type
is the data type of the elements in the collectionelement
is a variable that represents the current item being processedcollection
is the collection being iterated through
Simple Example: Iterating Through an Array
Let's start with a basic example of using foreach
to iterate through an array of integers:
using System;
class Program
{
static void Main()
{
// Define an array of integers
int[] numbers = { 1, 2, 3, 4, 5 };
// Use foreach to iterate through the array
Console.WriteLine("Numbers in the array:");
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}
}
Output:
Numbers in the array:
1
2
3
4
5
In this example, the foreach
loop automatically iterates through each element in the numbers
array. For each iteration, the current element is assigned to the number
variable, which we can then use inside the loop body.
Key Characteristics of the Foreach Loop
1. Read-Only Access
An important limitation to understand is that the foreach
loop provides read-only access to the collection elements. You cannot modify the collection element through the iteration variable:
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int number in numbers)
{
// This will cause a compilation error
// number = number * 2;
}
If you need to modify the elements, you should use a regular for
loop with index access, or store the modified values in a new collection.
2. No Index Access
Unlike the for
loop, the foreach
loop does not provide direct access to the index of the current element:
string[] fruits = { "Apple", "Banana", "Cherry" };
// If you need indices with foreach, you need to track them manually
int index = 0;
foreach (string fruit in fruits)
{
Console.WriteLine($"Fruit at index {index}: {fruit}");
index++;
}
Output:
Fruit at index 0: Apple
Fruit at index 1: Banana
Fruit at index 2: Cherry
Iterating Through Different Collection Types
The foreach
loop works with any collection type that implements the IEnumerable
interface. Let's explore a few examples:
Lists
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<string> cities = new List<string>
{
"New York",
"London",
"Tokyo",
"Paris",
"Sydney"
};
Console.WriteLine("Cities around the world:");
foreach (string city in cities)
{
Console.WriteLine(city);
}
}
}
Output:
Cities around the world:
New York
London
Tokyo
Paris
Sydney
Dictionaries
When iterating through a dictionary with foreach
, each element is a key-value pair:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, int> ages = new Dictionary<string, int>
{
{ "John", 28 },
{ "Mary", 24 },
{ "Steve", 32 },
{ "Lisa", 26 }
};
foreach (KeyValuePair<string, int> person in ages)
{
Console.WriteLine($"{person.Key} is {person.Value} years old");
}
// You can also use var for simpler code
Console.WriteLine("\nUsing var keyword:");
foreach (var person in ages)
{
Console.WriteLine($"{person.Key} is {person.Value} years old");
}
// If you only need the keys
Console.WriteLine("\nOnly names:");
foreach (string name in ages.Keys)
{
Console.WriteLine(name);
}
// If you only need the values
Console.WriteLine("\nOnly ages:");
foreach (int age in ages.Values)
{
Console.WriteLine(age);
}
}
}
Output:
John is 28 years old
Mary is 24 years old
Steve is 32 years old
Lisa is 26 years old
Using var keyword:
John is 28 years old
Mary is 24 years old
Steve is 32 years old
Lisa is 26 years old
Only names:
John
Mary
Steve
Lisa
Only ages:
28
24
32
26
Strings
Since strings in C# are collections of characters, you can use foreach
to iterate through each character in a string:
using System;
class Program
{
static void Main()
{
string message = "Hello";
Console.WriteLine("Characters in the message:");
foreach (char c in message)
{
Console.WriteLine(c);
}
}
}
Output:
Characters in the message:
H
e
l
l
o
Real-World Examples
Example 1: Processing Student Grades
Let's create a more practical example where we use a foreach
loop to calculate the average grade of students:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, List<double>> studentGrades = new Dictionary<string, List<double>>
{
{ "Alice", new List<double> { 92.5, 88.0, 95.5, 90.0 } },
{ "Bob", new List<double> { 85.0, 87.5, 77.0, 92.0 } },
{ "Charlie", new List<double> { 72.0, 81.5, 86.0, 78.5 } }
};
foreach (var student in studentGrades)
{
double sum = 0;
foreach (double grade in student.Value)
{
sum += grade;
}
double average = sum / student.Value.Count;
Console.WriteLine($"{student.Key}'s average grade: {average:F1}");
}
}
}
Output:
Alice's average grade: 91.5
Bob's average grade: 85.4
Charlie's average grade: 79.5
This example shows how foreach
loops can be nested to process more complex data structures.
Example 2: Filtering a Collection
Here's how you could use a foreach
loop alongside a List
to filter elements from a collection:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<int> allNumbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<int> evenNumbers = new List<int>();
foreach (int number in allNumbers)
{
if (number % 2 == 0)
{
evenNumbers.Add(number);
}
}
Console.WriteLine("Even numbers:");
foreach (int number in evenNumbers)
{
Console.Write($"{number} ");
}
}
}
Output:
Even numbers:
2 4 6 8 10
Using Foreach with Custom Classes
The foreach
loop can also be used with your custom classes as long as they implement the IEnumerable
or IEnumerable<T>
interface:
using System;
using System.Collections;
using System.Collections.Generic;
class BookCollection : IEnumerable<Book>
{
private List<Book> books = new List<Book>();
public void AddBook(Book book)
{
books.Add(book);
}
public IEnumerator<Book> GetEnumerator()
{
return books.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
class Book
{
public string Title { get; set; }
public string Author { get; set; }
public Book(string title, string author)
{
Title = title;
Author = author;
}
public override string ToString()
{
return $"{Title} by {Author}";
}
}
class Program
{
static void Main()
{
BookCollection myBooks = new BookCollection();
myBooks.AddBook(new Book("The Great Gatsby", "F. Scott Fitzgerald"));
myBooks.AddBook(new Book("To Kill a Mockingbird", "Harper Lee"));
myBooks.AddBook(new Book("1984", "George Orwell"));
Console.WriteLine("My Book Collection:");
foreach (Book book in myBooks)
{
Console.WriteLine(book);
}
}
}
Output:
My Book Collection:
The Great Gatsby by F. Scott Fitzgerald
To Kill a Mockingbird by Harper Lee
1984 by George Orwell
Foreach vs. For Loop: When to Use Each
While foreach
is simpler and cleaner, there are situations where a traditional for
loop might be more appropriate:
-
Use
foreach
when:- You need to process all elements in a collection
- You don't need to modify the elements
- You don't need the index of the current element
- You want cleaner, more readable code
-
Use
for
when:- You need to modify the elements in the collection
- You need access to the element index
- You need to skip elements or process them in a specific order
- You need more control over the iteration process
Summary
The foreach
loop is a powerful and elegant feature in C# that simplifies collection traversal. Its main advantages are:
- Simplicity and readability
- No need for explicit indexing or bounds checking
- Works with any collection that implements
IEnumerable
- Helps prevent common errors like index out-of-bounds
However, it also has some limitations, such as read-only access to collection elements and no direct access to element indices.
Understanding when and how to use the foreach
loop is an essential skill for any C# programmer, as it makes your code cleaner, more readable, and less prone to errors.
Practice Exercises
- Create a program that uses a
foreach
loop to find the maximum value in an array of integers. - Write a program that uses a
foreach
loop to count the number of vowels in a string. - Create a program with a
List
of student objects (with properties like Name and Grade), and use aforeach
loop to find all students who received an A (grade >= 90). - Write a program that uses nested
foreach
loops to print out all combinations of two lists.
Additional Resources
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)