foreach, in (C#-Referenz)foreach, in (C# reference)

Die Anweisung foreach führt eine Anweisung oder einen Block von Anweisungen für jedes Element in einer Instanz des Typs aus, der die Schnittstellen System.Collections.IEnumerable oder System.Collections.Generic.IEnumerable<T> implementiert. Dies wird im folgenden Beispiel gezeigt: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}");

Die Anweisung foreach ist nicht auf diese Typen beschränkt.The foreach statement isn't limited to those types. Sie können sie mit einer Instanz eines beliebigen Typs verwenden, der die folgenden Bedingungen erfüllt:You can use it with an instance of any type that satisfies the following conditions:

  • Ein Typ weist die öffentliche parameterlose Methode GetEnumerator auf, deren Rückgabetyp entweder eine Klasse, eine Struktur oder ein Schnittstellentyp ist.A type has the public parameterless GetEnumerator method whose return type is either class, struct, or interface type. Ab C# 9.0 kann die GetEnumerator-Methode die Erweiterungsmethode eines Typs sein.Beginning with C# 9.0, the GetEnumerator method can be a type's extension method.
  • Der Rückgabetyp der Methode GetEnumerator weist die öffentliche Eigenschaft Current und die öffentliche parameterlose Methode MoveNext auf, deren Rückgabetyp Boolean ist.The return type of the GetEnumerator method has the public Current property and the public parameterless MoveNext method whose return type is Boolean.

Im folgenden Beispiel wird die Anweisung foreach mit einer Instanz des Typs System.Span<T> verwendet, der keine Schnittstellen implementiert: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();
    }
}

Ab C# 7.3 können Sie die Iterationsvariable mit den Modifizierern ref oder ref readonly deklarieren, wenn die Eigenschaft Current des Enumerators einen Verweisrückgabewert (ref T, wobei T dem Typ des Sammlungselements entspricht) zurückgibt. Dies wird im folgenden Beispiel gezeigt: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
    }
}

Ab C# 8.0 können Sie die Anweisung await foreach verwenden, um einen asynchronen Datenstrom zu verarbeiten, also den Sammlungstyp, der die Schnittstelle IAsyncEnumerable<T> implementiert.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. Jede Iteration der Schleife kann unterbrochen werden, während das nächste Element asynchron abgerufen wird.Each iteration of the loop may be suspended while the next element is retrieved asynchronously. Im folgenden Beispiel wird veranschaulicht, wie Sie die Anweisung await foreach verwenden:The following example shows how to use the await foreach statement:

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

Standardmäßig werden Streamelemente im erfassten Kontext verarbeitet.By default, stream elements are processed in the captured context. Wenn Sie die Erfassung des Kontexts deaktivieren möchten, verwenden Sie die Erweiterungsmethode TaskAsyncEnumerableExtensions.ConfigureAwait.If you want to disable capturing of the context, use the TaskAsyncEnumerableExtensions.ConfigureAwait extension method. Weitere Informationen über Synchronisierungskontexte und die Erfassung des aktuellen Kontexts finden Sie im Artikel Verwenden des aufgabenbasierten asynchronen Musters.For more information about synchronization contexts and capturing the current context, see Consuming the Task-based asynchronous pattern. Weitere Informationen finden Sie im Abschnitt Asynchrone Datenströme des Artikels Neues in C# 8.0.For more information about asynchronous streams, see the Asynchronous streams section of the What's new in C# 8.0 article.

Sie können die Schleife an jedem Punkt im foreach-Anweisungsblock mit der Anweisung break unterbrechen oder mit der Anweisung continue direkt zum nächsten Durchlauf der Schleife springen.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. Sie können eine foreach-Schleife auch mit den Anweisungen goto, return oder throw beenden.You can also exit a foreach loop by the goto, return, or throw statements.

Wenn die foreach-Anweisung auf null angewendet wird, wird NullReferenceException ausgelöst.If the foreach statement is applied to null, a NullReferenceException is thrown. Falls die Quellsammlung der foreach-Anweisung leer ist, wird der Text der foreach-Schleife nicht ausgeführt und übersprungen.If the source collection of the foreach statement is empty, the body of the foreach loop isn't executed and skipped.

Typ einer IterationsvariablenType of an iteration variable

Sie können das Schlüsselwort var verwenden, damit der Compiler den Typ einer Iterationsvariablen in der Anweisung foreach ableiten kann. Dies wird im folgenden Code gezeigt: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) { }

Sie können auch wie im folgenden Code explizit den Typ einer Iterationsvariablen angeben: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) { }

Im obigen Formular muss der Typ T eines Sammlungselements implizit oder explizit in Typ V einer Iterationsvariablen konvertierbar sein.In the preceding form, type T of a collection element must be implicitly or explicitly convertible to type V of an iteration variable. Wenn eine explizite Konvertierung von T in V zur Laufzeit fehlschlägt, löst die Anweisung foreach eine InvalidCastException aus.If an explicit conversion from T to V fails at run time, the foreach statement throws an InvalidCastException. Wenn T z. B. ein nicht versiegelter Klassentyp ist, kann V ein beliebiger Schnittstellentyp sein – sogar der Typ, den T nicht implementiert.For example, if T is a non-sealed class type, V can be any interface type, even the one that T doesn't implement. Zur Laufzeit kann der Typ eines Sammlungselements der Typ sein, der von T abgeleitet wird und V implementiert.At run time, the type of a collection element may be the one that derives from T and actually implements V. Wenn dies nicht der Fall ist, wird eine InvalidCastException ausgelöst.If that's not the case, an InvalidCastException is thrown.

C#-SprachspezifikationC# language specification

Weitere Informationen finden Sie im Abschnitt Die foreach-Anweisung der C#-Sprachspezifikation.For more information, see The foreach statement section of the C# language specification.

Weitere Informationen zu in C# 8.0 und höher eingeführten Features finden Sie in den folgenden Featurevorschlägen:For more information about features added in C# 8.0 and later, see the following feature proposal notes:

Weitere InformationenSee also