Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

C# Dictionary

  1. Home
  2. C# Dictionary
  3. foreach Statement (C#)

foreach Statement (C#)

The basic syntax of the foreach statement, which iterates over all elements in a collection or array. In C#, foreach works with any type that implements the IEnumerable interface, letting you retrieve elements one by one without managing an index. This page also covers alternatives when you need an index and when to use for instead.

Syntax

The basic form and common patterns of the foreach statement.

foreach (type variable in collection) {
	// Executed once for each element.
	// The current element is automatically assigned to variable.
}

// You can also use var for type inference (recommended).
foreach (var variable in collection) {
	// The type is inferred from the element type of the collection.
}

// Use break to exit the loop early.
foreach (var variable in collection) {
	if (condition) {
		break; // Exits the entire loop.
	}
}

// Use continue to skip the current iteration.
foreach (var variable in collection) {
	if (condition) {
		continue; // Skips the rest of this iteration and moves to the next.
	}
}

Types that support foreach

foreach works with any type that implements IEnumerable or IEnumerable<T>. All major collections in the standard library implement this interface.

Typeforeach supportNotes
Array (T[])SupportedImplements IEnumerable<T>.
List<T>SupportedThe most commonly used collection type.
Dictionary<TKey, TValue>SupportedEach element is retrieved as a KeyValuePair<TKey, TValue>.
HashSet<T>SupportedOrder is not guaranteed.
Custom class implementing IEnumerable<T>SupportedImplement GetEnumerator() to enable foreach support.
Scalar types such as int or stringNot supportedResults in a compile error.

When to use for vs. foreach

SituationRecommendedReason
Simply iterating over all elements in orderforeachNo index needed; keeps the code simple.
Index is requiredfor or Select with indexforeach alone does not provide an index.
Reverse order or custom stepforThe counter variable can be manipulated freely.
Modifying elements in placeforThe foreach variable is a copy, so assigning to it does not modify the original collection.
Processing IEnumerable directly (lazy evaluation)foreachWorks with non-IList types such as LINQ query results.

Sample code

ForeachBasic.cs

Demonstrates foreach over arrays and lists, with break and continue.

using System;
using System.Collections.Generic;

class ForeachBasic {
	static void Main() {

		// Prints each item's name in order.
		string[] items = { "item_a", "item_b", "item_c", "item_d", "item_e" };

		Console.WriteLine("=== Item List ===");
		foreach (string item in items) {
			// item is automatically assigned the current element each iteration.
			Console.WriteLine("Item: " + item);
		}

		// Stores scores in a List and calculates the total.
		List<int> scores = new List<int> { 90, 85, 35, 15, 8 };

		Console.WriteLine("\n=== Score Total ===");
		int total = 0;
		foreach (var score in scores) {
			// Using var, the type is inferred as int automatically.
			total += score;
			Console.WriteLine("Score: " + score);
		}
		Console.WriteLine("Total score: " + total);

		// Searches for a specific name in a list without needing an index.
		// foreach + break is easy to read for simple searches like this.
		string[] sorted = { "item_d", "item_c", "item_b", "item_a", "item_e" };
		string target = "item_b";

		Console.WriteLine("\n=== Searching for " + target + " ===");
		foreach (string name in sorted) {
			Console.WriteLine("Checking " + name + "...");
			if (name == target) {
				Console.WriteLine("Found " + target + "! Search complete.");
				break; // Target found; exit the loop.
			}
		}

		// Prints all items except item_e.
		Console.WriteLine("\n=== Items excluding item_e ===");
		foreach (string name in items) {
			if (name == "item_e") {
				continue; // Skip this iteration and move to the next.
			}
			Console.WriteLine(name);
		}
	}
}

This produces the following output:

dotnet script ForeachBasic.cs
=== Item List ===
Item: item_a
Item: item_b
Item: item_c
Item: item_d
Item: item_e

=== Score Total ===
Score: 90
Score: 85
Score: 35
Score: 15
Score: 8
Total score: 233

=== Searching for item_b ===
Checking item_d...
Checking item_c...
Checking item_b...
Found item_b! Search complete.

=== Items excluding item_e ===
item_a
item_b
item_c
item_d
ForeachWithIndex.cs

Three alternatives for obtaining an index with foreach, plus foreach over a Dictionary.

using System;
using System.Collections.Generic;
using System.Linq;

class ForeachWithIndex {
	static void Main() {

		// foreach does not provide an index by default.
		// Here are three alternatives when you need one.

		string[] phases = {
			"Phase 1",
			"Phase 2",
			"Phase 3",
			"Phase 4"
		};

		Console.WriteLine("=== Option 1: for loop ===");
		for (int i = 0; i < phases.Length; i++) {
			Console.WriteLine((i + 1) + ". " + phases[i]);
		}

		// Available in .NET 6 and later with Select((element, index) => ...).
		Console.WriteLine("\n=== Option 2: Select with index (LINQ) ===");
		foreach (var item in phases.Select((phase, index) => new { phase, index })) {
			// Access the index via item.index and the element via item.phase.
			Console.WriteLine((item.index + 1) + ". " + item.phase);
		}

		Console.WriteLine("\n=== Option 3: Manual counter ===");
		int count = 0; // Declare the counter outside the foreach.
		foreach (var phase in phases) {
			count++;
			Console.WriteLine(count + ". " + phase);
		}

		// Each entry is retrieved as a KeyValuePair<TKey, TValue>.
		Console.WriteLine("\n=== foreach over a Dictionary ===");
		var scoreDict = new Dictionary<string, int> {
			{ "item_a", 90 },
			{ "item_b", 85 },
			{ "item_c", 120 },
			{ "item_d", 35 }
		};

		foreach (var kvp in scoreDict) {
			// Access the key via kvp.Key and the value via kvp.Value.
			Console.WriteLine(kvp.Key + " score: " + kvp.Value);
		}
	}
}

This produces the following output:

dotnet script ForeachWithIndex.cs
=== Option 1: for loop ===
1. Phase 1
2. Phase 2
3. Phase 3
4. Phase 4

=== Option 2: Select with index (LINQ) ===
1. Phase 1
2. Phase 2
3. Phase 3
4. Phase 4

=== Option 3: Manual counter ===
1. Phase 1
2. Phase 2
3. Phase 3
4. Phase 4

=== foreach over a Dictionary ===
item_a score: 90
item_b score: 85
item_c score: 120
item_d score: 35
ForeachIEnumerable.cs

A custom collection that supports foreach by implementing IEnumerable<T>.

using System;
using System.Collections;
using System.Collections.Generic;

// A custom collection that supports foreach by implementing IEnumerable<T>.
// Manages a roster of item names.
class ItemRoster : IEnumerable<string> {

	private List<string> entries = new List<string>();

	// Adds an item to the roster.
	public void Add(string name) {
		entries.Add(name);
	}

	// IEnumerable<T> implementation: providing GetEnumerator() enables foreach.
	public IEnumerator<string> GetEnumerator() {
		return entries.GetEnumerator();
	}

	// The non-generic IEnumerable implementation is also required.
	IEnumerator IEnumerable.GetEnumerator() {
		return GetEnumerator();
	}
}

class ForeachIEnumerable {
	static void Main() {

		var roster = new ItemRoster();
		roster.Add("item_a");
		roster.Add("item_b");
		roster.Add("item_c");
		roster.Add("item_d");
		roster.Add("item_e");

		Console.WriteLine("=== Roster ===");
		foreach (string name in roster) {
			// ItemRoster implements IEnumerable<string>, so foreach works here.
			Console.WriteLine("Registered: " + name);
		}

		// Where, Select, and other LINQ methods are available on any IEnumerable<T>.
		Console.WriteLine("\n=== Names with 6 or more characters ===");
		foreach (string name in roster) {
			if (name.Length >= 6) {
				Console.WriteLine(name + " (" + name.Length + " chars)");
			}
		}
	}
}

This produces the following output:

dotnet script ForeachIEnumerable.cs
=== Roster ===
Registered: item_a
Registered: item_b
Registered: item_c
Registered: item_d
Registered: item_e

=== Names with 6 or more characters ===
item_a (6 chars)
item_b (6 chars)
item_c (6 chars)
item_d (6 chars)
item_e (6 chars)

Common Mistakes

Modifying a collection during foreach

Adding or removing elements from a collection (such as List<T>) while iterating over it with foreach throws an InvalidOperationException. The internal enumerator detects the modification and raises the exception.

var names = new List<string> { "item_a", "item_b", "item_c" };

// Throws InvalidOperationException.
foreach (var name in names) {
	if (name == "item_b") {
		names.Remove(name); // Modifying the collection during iteration is not allowed.
	}
}

To remove elements, either use a for loop in reverse order or use LINQ's Where() to create a new list excluding the unwanted elements.

for (int i = names.Count - 1; i >= 0; i--) {
	if (names[i] == "item_b") {
		names.RemoveAt(i);
	}
}

names = names.Where(n => n != "item_b").ToList();

Assigning to the loop variable does not modify the original collection

The foreach loop variable is a copy of each element (for value types) or a copy of the reference. Assigning a value to the loop variable does not affect the original collection. In C#, this results in a compile error.

int[] scores = { 80, 90, 70 };

foreach (var score in scores) {
	// score = score + 10; // Compile error: cannot assign to the foreach iteration variable.
}

// Use a for loop to modify elements in place.
for (int i = 0; i < scores.Length; i++) {
	scores[i] = scores[i] + 10; // The original array is updated.
}

Overview

The C# foreach statement processes all elements of a type that implements IEnumerable / IEnumerable<T> in order from first to last. The loop variable inside foreach is a copy of each element (for value types) or a copy of the reference, so assigning a value to the loop variable does not modify the original collection. To modify elements in place, use a for loop with an index for direct assignment.

Because foreach does not provide an index, use a for loop, a manual counter, or LINQ's Select((element, index) => ...) when you need to know the position of an element. A for loop is also the right choice when you need to iterate in reverse or with a custom step (see for loop).

Custom classes can also support foreach by implementing IEnumerable<T> with a GetEnumerator() method. Because LINQ methods such as Where and Select accept IEnumerable<T>, any type that supports foreach can be used directly in a LINQ chain (see also Enumerable.Where and IEnumerable / IList).

If you find any errors or copyright issues, please .