Sdílet prostřednictvím


Iterační příkazy - for, foreach, doa while

Příkazy iterace slouží k opakovanému spuštění příkazu nebo bloku příkazů. Příkaz for spustí jeho tělo, zatímco zadaný logický výraz se vyhodnotí jako true. Příkaz foreach vyčíslí prvky kolekce a spustí jeho tělo pro každý prvek kolekce. Příkaz do podmíněně provede jeho tělo jednou nebo vícekrát. Příkaz while podmíněně provede jeho tělo nula nebo vícekrát.

V jakémkoli okamžiku v těle příkazu iterace můžete smyčku ukončit pomocí break příkazu. Pomocí příkazu můžete přejít k další iteraci ve smyčcecontinue.

Referenční dokumentace jazyka C# dokumentuje naposledy vydané verze jazyka C#. Obsahuje také počáteční dokumentaci k funkcím ve verzi Public Preview pro nadcházející jazykovou verzi.

Dokumentace identifikuje všechny funkce, které byly poprvé představeny v posledních třech verzích jazyka nebo v aktuálních verzích Public Preview.

Návod

Informace o tom, kdy byla funkce poprvé představena v jazyce C#, najdete v článku o historii verzí jazyka C#.

Příkaz for

Příkaz for spustí příkaz nebo blok příkazů, zatímco zadaný logický výraz se vyhodnotí jako true. Následující příklad ukazuje for příkaz, který provede své tělo, pokud je celočíselný čítač menší než tři.

for (int i = 0; i < 3; i++)
{
    Console.Write(i);
}
// Output:
// 012

Předchozí příklad ukazuje prvky for příkazu:

  • Oddíl inicializátoru , který se provede pouze jednou, před vstupem do smyčky. Obvykle deklarujete a inicializujete proměnnou místní smyčky v této části. Deklarovanou proměnnou nemůžete získat přístup z vnějšího for příkazu.

    Část inicializátoru v předchozím příkladu deklaruje a inicializuje celočíselnou čítačovou proměnnou.

    int i = 0
    
  • Část podmínky , která určuje, jestli se má spustit další iterace ve smyčce. Pokud se vyhodnotí true jako nebo není k dispozici, spustí se další iterace. V opačném případě se smyčka ukončí. Oddíl podmínky musí být logickým výrazem.

    Část podmínky v předchozím příkladu zkontroluje, jestli je hodnota čítače menší než tři:

    i < 3
    
  • Oddíl iterátoru který definuje, co se stane po každém spuštění těla smyčky.

    Sekce iterátoru v předchozím příkladu zvyšuje čítač:

    i++
    
  • Tělo smyčky, které musí být příkazem nebo blokem příkazů.

Oddíl iterátoru může obsahovat nula nebo více následujících výrazů příkazů oddělených čárkami:

Pokud v oddílu inicializátoru nevyhlásíte proměnnou smyčky, můžete také použít nula nebo více výrazů z předchozího seznamu v oddílu inicializátoru. Následující příklad ukazuje několik méně běžných použití oddílů inicializátoru a iterátoru: přiřazení hodnoty externí proměnné v oddílu inicializátoru, vyvolání metody v oddílech inicializátoru i iterátoru a změna hodnot dvou proměnných v oddílu iterátoru:

int i;
int j = 3;
for (i = 0, Console.WriteLine($"Start: i={i}, j={j}"); i < j; i++, j--, Console.WriteLine($"Step: i={i}, j={j}"))
{
    //...
}
// Output:
// Start: i=0, j=3
// Step: i=1, j=2
// Step: i=2, j=1

Všechny oddíly for příkazu jsou volitelné. Například následující kód definuje nekonečnou for smyčku:

for ( ; ; )
{
    //...
}

Příkaz foreach

Příkaz foreach spustí příkaz nebo blok příkazů pro každý prvek v instanci typu, který implementuje System.Collections.IEnumerable nebo System.Collections.Generic.IEnumerable<T> rozhraní, jak ukazuje následující příklad:

List<int> fibNumbers = new() { 0, 1, 1, 2, 3, 5, 8, 13 };
foreach (int element in fibNumbers)
{
    Console.Write($"{element} ");
}
// Output:
// 0 1 1 2 3 5 8 13

Příkaz foreach není omezen na tyto typy. Můžete ho použít s instancí libovolného typu, který splňuje následující podmínky:

  • Typ má veřejnou metodu bez GetEnumerator parametrů. Metoda GetEnumerator může být rozšiřující metodou.
  • Návratový GetEnumerator typ metody má veřejnou vlastnost a veřejnou Current bezparametrovou MoveNext metodu, jejíž návratový typ je bool.

Následující příklad používá foreach příkaz s instancí System.Span<T> typu, která neimplementuje žádná rozhraní:

Span<int> numbers = [3, 14, 15, 92, 6];
foreach (int number in numbers)
{
    Console.Write($"{number} ");
}
// Output:
// 3 14 15 92 6

Pokud vlastnost enumerátoru Current vrátí návratovou hodnotu odkazu (ref T kde T je typ prvku kolekce), můžete deklarovat iterační proměnnou pomocí ref nebo ref readonly modifikátoru, jak ukazuje následující příklad:

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

Pokud je zdrojová foreach kolekce příkazu prázdná, foreach tělo příkazu se nespustí a přeskočí. Pokud je na foreach aplikován null, je vyvolána výjimka NullReferenceException.

await foreach

await foreach Pomocí příkazu můžete využívat asynchronní datový proud, tj. typ kolekce, který implementuje IAsyncEnumerable<T> rozhraní. Každá iterace smyčky může pozastavit, zatímco další prvek je načten asynchronně. Následující příklad ukazuje, jak použít await foreach příkaz:

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

Také můžete použít příkaz await foreach s instancí libovolného typu, který splňuje následující podmínky:

  • Typ má veřejnou metodu bez GetAsyncEnumerator parametrů. Tato metoda může být členem rozšíření.
  • Návratový typ metody GetAsyncEnumerator má veřejnou vlastnost Current a veřejnou bezparametrovou metodu MoveNextAsync, jejíž návratový typ je Task<bool>, ValueTask<bool> nebo jakýkoli jiný typ, který je awaitable, jehož metoda GetResult v awaiteru vrací hodnotu bool.

Příkaz ve výchozím nastavení await foreach zpracovává elementy streamu v zachyceného kontextu. Pokud chcete zakázat zachytávání kontextu, použijte metodu TaskAsyncEnumerableExtensions.ConfigureAwait rozšíření. Další informace o kontextech synchronizace a zachycení aktuálního kontextu naleznete v tématu Využívání asynchronního vzoru založeného na úlohách. Další informace o asynchronních datových proudech najdete v kurzu asynchronních datových proudů.

Typ iterace proměnné

var Klíčové slovo použijte k tomu, aby kompilátor odvodil typ proměnné iterace v foreach příkazu, jak ukazuje následující kód:

foreach (var item in collection) { }

Poznámka:

Kompilátor může odvodit typ var deklarace jako odkazový typ s možnou hodnotou null v závislosti na tom, zda je povolen kontext s podporou null a zda typ inicializačního výrazu je odkazový typ. Další informace naleznete v tématu Implicitně typované místní proměnné.

Můžete také explicitně zadat typ proměnné iterace, jak ukazuje následující kód:

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

V předchozím formuláři musí být typ T elementu kolekce implicitně nebo explicitně konvertibilní na typ V proměnné iterace. Pokud explicitní převod z T na V selže za běhu, příkaz foreach vyvolá InvalidCastException výjimku. Pokud T je například nezapečetěný typ třídy, V může to být jakýkoli typ rozhraní, i ten, který T neimplementuje. V době běhu může být typ elementu kolekce, který je odvozen od T a skutečně implementuje V. Je-li tomu jinak, je vyvolán InvalidCastException.

Příkaz do

Příkaz do spustí příkaz nebo blok příkazů, zatímco zadaný logický výraz se vyhodnotí jako true. Vzhledem k tomu, že smyčka tento výraz vyhodnotí po každém spuštění, smyčka do se provede jednou nebo vícekrát. Smyčka do se liší od smyčky while, která se může provést nula nebo vícekrát.

Následující příklad ukazuje použití do příkazu:

int n = 0;
do
{
    Console.Write(n);
    n++;
} while (n < 5);
// Output:
// 01234

Příkaz while

Příkaz while spustí příkaz nebo blok příkazů, zatímco zadaný logický výraz se vyhodnotí jako true. Vzhledem k tomu, že smyčka tento výraz vyhodnotí před každým spuštěním, smyčka while se provede nulou nebo vícekrát. Smyčka while se liší od do smyčky, která se spouští jednou nebo vícekrát.

Následující příklad ukazuje použití while příkazu:

int n = 0;
while (n < 5)
{
    Console.Write(n);
    n++;
}
// Output:
// 01234

Specifikace jazyka C#

Další informace najdete v následujících částech specifikace jazyka C#:

Viz také