Read the syntax
foreach obtains an enumerator and visits each item in a sequence. The loop variable receives one element per iteration; you do not manage indexes yourself.
IEnumerable<T> describes a typed sequence. A custom GetEnumerator can yield items lazily, and var can infer the type of each item when spelling it out would be noisy.
Syntax
foreach (Type item in collection) {\n // code\n}Examples
Basic foreach Usage
Iterating over different built-in collection types with the same syntax.
List<string> names = new List<string> { "John", "Zain", "Jamal" };
foreach (string name in names)
{
Console.WriteLine(name);
}
int[] numbers = { 1, 2, 3 };
foreach (int n in numbers)
{
Console.WriteLine(n * n);
}- Iterating over different built-in collection types with the same syntax.
- foreach obtains an enumerator and visits each item in a sequence. The loop variable receives one element per iteration; you do not manage indexes yourself.
- The first foreach prints each name. The second squares the values from the integer array and prints 1, 4 and 9.
foreach with var
Using var lets the compiler infer the element type, useful when working with complex generic types.
Dictionary<string, int> scores = new Dictionary<string, int>
{
["Alice"] = 85,
["Bob"] = 92
};
foreach (var entry in scores) // type inferred as KeyValuePair<string, int>
{
Console.WriteLine($"{entry.Key}: {entry.Value}");
}- Using var lets the compiler infer the element type, useful when working with complex generic types.
- foreach obtains an enumerator and visits each item in a sequence. The loop variable receives one element per iteration; you do not manage indexes yourself.
- The compiler infers entry as a KeyValuePair<string,int>, so Key and Value are available inside the loop. Each dictionary score is printed.
Implementing IEnumerable in a Custom Class
Making a custom class support foreach by implementing IEnumerable<T>, often with a yield return generator method.
foreach (int n in new NumberRange(1, 5))
{
Console.WriteLine(n); // 1, 2, 3, 4, 5
}
public class NumberRange : IEnumerable<int>
{
private int _start, _end;
public NumberRange(int start, int end) { _start = start; _end = end; }
public IEnumerator<int> GetEnumerator()
{
for (int i = _start; i <= _end; i++)
yield return i;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
=> GetEnumerator();
}- Making a custom class support foreach by implementing IEnumerable<T>, often with a yield return generator method.
- foreach obtains an enumerator and visits each item in a sequence. The loop variable receives one element per iteration; you do not manage indexes yourself.
- NumberRange yields each integer from _start through _end when foreach requests it. The example prints 1 through 5 without first building an array.
Best practices
- Use foreach by default for reading through a collection - it is safer and more readable than a manual indexed loop
- Don't modify a collection's structure (adding/removing items) while iterating over it with foreach - it throws an InvalidOperationException
- Implement IEnumerable<T> on a custom class when it genuinely represents a collection of things, so it works naturally with foreach and LINQ
- Use yield return inside GetEnumerator() (or any iterator method) for a concise way to implement custom iteration logic
Runtime & versions
.NET runtime. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
C# language reference