foreach, in (Referenční dokumentace jazyka C#)foreach, in (C# reference)

foreachPříkaz spustí příkaz nebo blok příkazů pro každý prvek v instanci typu, který implementuje System.Collections.IEnumerable System.Collections.Generic.IEnumerable<T> rozhraní nebo, jak ukazuje následující příklad: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)
{
    Console.WriteLine($"Element #{count}: {element}");
    count++;
}
Console.WriteLine($"Number of elements: {count}");

foreachPříkaz není omezen na tyto typy.The foreach statement isn't limited to those types. Můžete ji použít s instancí libovolného typu, který splňuje následující podmínky:You can use it with an instance of any type that satisfies the following conditions:

  • Typ má metodu public bez parametrů GetEnumerator , jejíž návratový typ je buď třída, struktura, nebo typ rozhraní.A type has the public parameterless GetEnumerator method whose return type is either class, struct, or interface type. Počínaje jazykem C# 9,0 GetEnumerator může být metodou rozšiřující metodatypu.Beginning with C# 9.0, the GetEnumerator method can be a type's extension method.
  • Návratový typ GetEnumerator metody má veřejnou Current vlastnost a metodu public bez parametrů, MoveNext jejíž návratový typ je Boolean .The return type of the GetEnumerator method has the public Current property and the public parameterless MoveNext method whose return type is Boolean.

Následující příklad používá foreach příkaz s instancí System.Span<T> typu, který neimplementuje žádná rozhraní: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();
    }
}

Počínaje jazykem C# 7,3, pokud vlastnost enumerátoru Current vrátí návratovou hodnotu odkazu ( ref T kde T je typ prvku kolekce), můžete deklarovat proměnnou iterace pomocí ref ref readonly modifikátoru nebo, jak ukazuje následující příklad: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
    }
}

Počínaje jazykem C# 8,0 můžete použít await foreach příkaz pro využívání asynchronního datového proudu dat, tedy typu kolekce, který implementuje IAsyncEnumerable<T> rozhraní.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. Každá iterace smyčky může být pozastavena, zatímco je další prvek načten asynchronně.Each iteration of the loop may be suspended while the next element is retrieved asynchronously. Následující příklad ukazuje, jak použít await foreach příkaz:The following example shows how to use the await foreach statement:

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

Ve výchozím nastavení jsou prvky Stream zpracovávány v zachyceném kontextu.By default, stream elements are processed in the captured context. Pokud chcete zakázat zachycování kontextu, použijte TaskAsyncEnumerableExtensions.ConfigureAwait metodu rozšíření.If you want to disable capturing of the context, use the TaskAsyncEnumerableExtensions.ConfigureAwait extension method. Další informace o kontextech synchronizace a záznamech aktuálního kontextu naleznete v tématu spotřebovávání asynchronního vzoru založeného na úlohách.For more information about synchronization contexts and capturing the current context, see Consuming the Task-based asynchronous pattern. Další informace o asynchronních datových proudech naleznete v části asynchronní datové proudy v článku novinky v C# 8,0 .For more information about asynchronous streams, see the Asynchronous streams section of the What's new in C# 8.0 article.

V jakémkoli bodě foreach bloku příkazu můžete přerušit smyčku pomocí příkazu Break nebo krokovat s další iterací ve smyčce pomocí příkazu Continue .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. Můžete také ukončit foreach smyčku příkazy goto, returnnebo throw .You can also exit a foreach loop by the goto, return, or throw statements.

Pokud foreach je příkaz použit na null , NullReferenceException je vyvolána.If the foreach statement is applied to null, a NullReferenceException is thrown. Pokud je zdrojová kolekce foreach příkazu prázdná, tělo foreach smyčky se neprovede a přeskočí.If the source collection of the foreach statement is empty, the body of the foreach loop isn't executed and skipped.

Typ proměnné iteraceType of an iteration variable

Klíčové slovo lze použít var k umožnění kompilátoru odvodit typ iterační proměnné v foreach příkazu, jak ukazuje následující kód: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) { }

Můžete také explicitně zadat typ proměnné iterace, jak ukazuje následující kód: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) { }

V předchozím formuláři T musí být typ elementu kolekce implicitně nebo explicitně převoditelné na typ V proměnné iterace.In the preceding form, type T of a collection element must be implicitly or explicitly convertible to type V of an iteration variable. Pokud explicitní převod z T na V neuspěje v době běhu, foreach příkaz vyvolá výjimku InvalidCastException .If an explicit conversion from T to V fails at run time, the foreach statement throws an InvalidCastException. Například pokud T je typ třídy, který není zapečetěný, V může být libovolný typ rozhraní, a to i ten, který T neimplementuje.For example, if T is a non-sealed class type, V can be any interface type, even the one that T doesn't implement. V době běhu může být typ elementu kolekce ten, který je odvozen z T a skutečně implementuje V .At run time, the type of a collection element may be the one that derives from T and actually implements V. V takovém případě InvalidCastException je vyvolána výjimka.If that's not the case, an InvalidCastException is thrown.

specifikace jazyka C#C# language specification

Další informace naleznete v oddílu foreach příkazu specifikace jazyka C#.For more information, see The foreach statement section of the C# language specification.

Další informace o funkcích přidaných v C# 8,0 a novějších verzích najdete v následujících poznámkách k návrhu funkcí:For more information about features added in C# 8.0 and later, see the following feature proposal notes:

Viz takéSee also