Příkazy iterace (Referenční dokumentace jazyka C#)

Následující příkazy opakovaně spouští příkaz nebo blok příkazů:

  • Příkazfor spustí své tělo, zatímco se zadaný logický výraz vyhodnotí jako true.
  • Příkazforeach: vytvoří výčet prvků kolekce a spustí její tělo pro každý prvek kolekce.
  • Příkazdo: Podmíněně spustí své tělo jednou nebo vícekrát.
  • Příkazwhile: Podmíněně spustí své tělo nulakrát nebo vícekrát.

V libovolném okamžiku v těle příkazu iterace můžete přerušit smyčku pomocí příkazu break nebo krokovat k další iteraci ve smyčce pomocí příkazu continue .

Příkaz for

Příkaz for provede 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ý spustí své tělo, zatímco celočíselný čítač je 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. Deklarovaná proměnná není přístupná z vnějšku for příkazu .

    Část inicializátoru v předchozím příkladu deklaruje a inicializuje proměnnou celočíselného čítače:

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

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

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

    Část iterátoru v předchozím příkladu zvýší čí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 proměnnou smyčky v oddílu inicializátoru nedeklarujete, můžete v oddílu inicializátoru použít také žádný nebo více výrazů z předchozího seznamu. 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ílu 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 rozhraní nebo System.Collections.Generic.IEnumerable<T> , jak ukazuje následující příklad:

var fibNumbers = new List<int> { 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ů. Počínaje jazykem C# 9.0 GetEnumerator může být metoda rozšiřující metodou typu.
  • Návratový typ GetEnumerator metody má veřejnou Current vlastnost a veřejnou 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 = new int[] { 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í hodnotu návratu odkazu (ref T kde T je typ prvku kolekce), můžete deklarovat iterační proměnnou s modifikátorem ref nebo ref readonly , 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 foreach příkaz použit na null, NullReferenceException je vyvolán . Pokud je zdrojová kolekce foreach příkazu prázdná, tělo foreach příkazu se nespustí a přeskočí.

await foreach

Pomocí příkazu můžete await foreach využívat asynchronní datový proud, tj. typ kolekce, který implementuje IAsyncEnumerable<T> rozhraní. Každá iterace smyčky může být pozastavena, 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);
}

Příkaz můžete použít await foreach také 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 rozšiřující metodou typu.
  • Návratový typ GetAsyncEnumerator metody má veřejnou Current vlastnost a veřejnou bezparametrovou MoveNextAsync metodu, jejíž návratový typ je Task<bool>, ValueTask<bool>nebo jakýkoli jiný typ awaitable, jehož metoda awaiter GetResult vrací bool hodnotu.

Ve výchozím nastavení se elementy datového proudu zpracovávají v zachycených kontextech. Pokud chcete zakázat zachytávání kontextu, použijte rozšiřující metodu TaskAsyncEnumerableExtensions.ConfigureAwait . Další informace o kontextech synchronizace a zachycení aktuálního kontextu najdete v tématu Využití asynchronního vzoru založeného na úlohách. Další informace o asynchronních datových proudech najdete v kurzu Asynchronní datové proudy.

Typ proměnné iterace

Klíčové slovo můžete použít var 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) { }

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ě převoditelný na typ V proměnné iterace. Pokud explicitní převod z T na V za běhu selže, foreach příkaz vyvolá .InvalidCastException Pokud je například T nezapečetěný typ třídy, V může to být libovolný typ rozhraní, i ten, který T neimplementuje. V době běhu může být typem elementu kolekce ten, který je odvozen z T a skutečně implementuje V. Pokud tomu tak není, je InvalidCastException vyvolán.

Příkaz do

Příkaz do provede příkaz nebo blok příkazů, zatímco zadaný logický výraz se vyhodnotí jako true. Vzhledem k tomu, že tento výraz je vyhodnocen po každém spuštění smyčky, do smyčka se spustí jednou nebo vícekrát. To se liší od smyčky While , která se spouští nulakrát 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 provede příkaz nebo blok příkazů, zatímco zadaný logický výraz se vyhodnotí jako true. Vzhledem k tomu, že se tento výraz vyhodnocuje před každým spuštěním while smyčky, smyčka se spustí nulakrát nebo vícekrát. To se liší od smyčky do , která se spustí 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#:

Další informace o funkcích přidaných v jazyce C# 8.0 a novějších najdete v následujících poznámkách k návrhu funkcí:

Viz také