foreach, in (C# reference)

The foreach statement executes a statement or a block of statements for each element in an instance of the type that implements the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T> interface, as the following example shows:

var fibNumbers = new List<int> { 0, 1, 1, 2, 3, 5, 8, 13 };
int count = 0;
foreach (int element in fibNumbers)
{
    count++;
    Console.WriteLine($"Element #{count}: {element}");
}
Console.WriteLine($"Number of elements: {count}");

The foreach statement isn't limited to those types. You can use it with an instance of any type that satisfies the following conditions:

  • a type has the public parameterless GetEnumerator method whose return type is either class, struct, or interface type,
  • the return type of the GetEnumerator method has the public Current property and the public parameterless MoveNext method whose return type is Boolean.

The following example uses the foreach statement with an instance of the System.Span<T> type, which doesn't implement any interfaces:

public class IterateSpanExample
{
    public static void Main()
    {
        Span<int> numbers = new int[] { 3, 14, 15, 92, 6 };
        foreach (int number in numbers)
        {
            Console.Write($"{number} ");
        }
        Console.WriteLine();
    }
}

Beginning with C# 7.3, if the enumerator's Current property returns a reference return value (ref T where T is the type of a collection element), you can declare an iteration variable with the ref or ref readonly modifier, as the following example shows:

public class ForeachRefExample
{
    public static void Main()
    {
        Span<int> storage = stackalloc int[10];
        int num = 0;
        foreach (ref int item in storage)
        {
            item = num++;
        }

        foreach (ref readonly var item in storage)
        {
            Console.Write($"{item} ");
        }
        // Output:
        // 0 1 2 3 4 5 6 7 8 9
    }
}

Beginning with C# 8.0, you can use the await foreach statement to consume an asynchronous stream of data, that is, the collection type that implements the IAsyncEnumerable<T> interface. Each iteration of the loop may be suspended while the next element is retrieved asynchronously. The following example shows how to use the await foreach statement:

await foreach (var item in GenerateSequenceAsync())
{
    Console.WriteLine(item);
}

By default, stream elements are processed in the captured context. If you want to disable capturing of the context, use the TaskAsyncEnumerableExtensions.ConfigureAwait extension method. For more information about synchronization contexts and capturing the current context, see Consuming the Task-based asynchronous pattern. For more information about asynchronous streams, see the Asynchronous streams section of the What's new in C# 8.0 article.

At any point within the foreach statement block, you can break out of the loop by using the break statement, or step to the next iteration in the loop by using the continue statement. You can also exit a foreach loop by the goto, return, or throw statements.

If the foreach statement is applied to null, a NullReferenceException is thrown. If the source collection of the foreach statement is empty, the body of the foreach loop isn't executed and skipped.

Type of an iteration variable

You can use the var keyword to let the compiler infer the type of an iteration variable in the foreach statement, as the following code shows:

foreach (var item in collection) { }

You can also explicitly specify the type of an iteration variable, as the following code shows:

IEnumerable<T> collection = new T[5];
foreach (V item in collection) { }

In the preceding form, type T of a collection element must be implicitly or explicitly convertible to type V of an iteration variable. If an explicit conversion from T to V fails at run time, the foreach statement throws an InvalidCastException. For example, if T is a non-sealed class type, V can be any interface type, even the one that T doesn't implement. At run time, the type of a collection element may be the one that derives from T and actually implements V. If that's not the case, an InvalidCastException is thrown.

C# language specification

For more information, see The foreach statement section of the C# language specification.

See also