Dela via


Iterationsinstruktioner – for, foreach, dooch while

Använd iterationsinstruktioner för att upprepade gånger köra en instruktion eller ett block med instruktioner. instruktionenfor exekverar sitt kodblock medan ett angivet booleskt uttryck utvärderas till true. foreach instruktionen räknar upp elementen i en samling och kör koddelen för varje element i samlingen. Instruktionendo kör villkorligt dess brödtext en eller flera gånger. Instruktionenwhile kör villkorsstyrt dess brödtext noll eller fler gånger.

När som helst i en iterationsuttrycks brödtext kan du avsluta loopen med hjälp av -instruktionenbreak. Du kan gå till nästa iteration i loopen med hjälp av -instruktionencontinue.

C#-språkreferensen dokumenterar den senaste versionen av C#-språket. Den innehåller även inledande dokumentation för funktioner i offentliga förhandsversioner för den kommande språkversionen.

Dokumentationen identifierar alla funktioner som först introducerades i de tre senaste versionerna av språket eller i aktuella offentliga förhandsversioner.

Tips/Råd

Information om när en funktion först introducerades i C# finns i artikeln om språkversionshistoriken för C#.

Påståendet for

-instruktionen for kör en instruktion eller ett block med -instruktioner medan ett angivet booleskt uttryck utvärderas till true. I följande exempel visas instruktionen for som körs medan en heltalsräknare är mindre än tre.

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

Föregående exempel visar elementen i uttrycket for.

  • Initieringsavsnittet som bara körs en gång innan du anger loopen. Vanligtvis deklarerar och initierar du en lokal loopvariabel i det avsnittet. Du kan inte komma åt den deklarerade variabeln utanför -instruktionen for .

    Initieringsavsnittet i föregående exempel deklarerar och initierar en heltalsräknare:

    int i = 0
    
  • Villkorsavsnittet som avgör om nästa iteration i loopen ska köras. Om den utvärderas till true eller inte finns körs nästa iteration. Annars avslutas loopen. Villkorsavsnittet måste vara ett booleskt uttryck.

    Villkorsavsnittet i föregående exempel kontrollerar om ett räknarvärde är mindre än tre:

    i < 3
    
  • Iteratoravsnittet som definierar vad som händer efter varje körning av loopens brödtext.

    Iteratoravsnittet i föregående exempel ökar räknaren:

    i++
    
  • Brödtexten i loopen, som måste vara en instruktion eller ett block med instruktioner.

Iteratoravsnittet kan innehålla noll eller fler av följande instruktionsuttryck, avgränsade med kommatecken:

Om du inte deklarerar en loopvariabel i initieringsavsnittet kan du även använda noll eller fler av uttrycken från föregående lista i avsnittet initialiserare. I följande exempel visas flera mindre vanliga användningar av initialiseraren och iteratoravsnitten: tilldela ett värde till en extern variabel i initieringsavsnittet, anropa en metod i både initialiseraren och iteratoravsnitten och ändra värdena för två variabler i iteratoravsnittet:

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

Alla avsnitt i for-instruktionen är valfria. Följande kod definierar till exempel den oändliga for loopen:

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

Påståendet foreach

-instruktionen foreach kör en instruktion eller ett block med instruktioner för varje element i en instans av typen som implementerar System.Collections.IEnumerable gränssnittet eller System.Collections.Generic.IEnumerable<T> , som följande exempel visar:

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

Instruktionen foreach är inte begränsad till dessa typer. Du kan använda den med en instans av vilken typ som helst som uppfyller följande villkor:

  • En typ har den offentliga parameterlösa GetEnumerator metoden. Metoden GetEnumerator kan vara en tilläggsmetod.
  • Returtypen för GetEnumerator metoden har den offentliga Current egenskapen och den offentliga parameterlösa MoveNext metoden vars returtyp är bool.

I följande exempel används -instruktionen foreach med en instans av System.Span<T> typen, som inte implementerar några gränssnitt:

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

Om uppräknarens egenskap returnerar ett Current ( där ref T är typen av ett samlingselementT) kan du deklarera en iterationsvariabel med ref eller ref readonly modifieraren, som följande exempel visar:

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

Om källsamlingen för -instruktionen foreach är tom körs inte instruktionens foreach brödtext och hoppas över. Om satsen `foreach` tillämpas på `null`, genereras en `NullReferenceException`.

await foreach

Använd -instruktionen await foreach för att använda en asynkron dataström, dvs. en samlingstyp som implementerar IAsyncEnumerable<T> gränssnittet. Varje iteration av loopen kan pausas medan nästa element hämtas asynkront. I följande exempel visas hur du använder instruktionen await foreach:

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

Du kan också använda -instruktionen await foreach med en instans av vilken typ som helst som uppfyller följande villkor:

  • En typ har den offentliga parameterlösa GetAsyncEnumerator metoden. Den här metoden kan vara en tilläggsmedlem.
  • Returtypen för GetAsyncEnumerator-metoden har den offentliga Current-egenskapen och den offentliga parameterlösa MoveNextAsync-metoden vars returtyp är Task<bool>, ValueTask<bool> eller någon annan väntbar typ vars GetResult-metod returnerar ett bool-värde.

Som standard bearbetar -instruktionen await foreach strömelement i den insamlade kontexten. Om du vill inaktivera infångning av kontexten använder du TaskAsyncEnumerableExtensions.ConfigureAwait tilläggsmetoden. Mer information om synkroniseringskontexter och insamling av den aktuella kontexten finns i Använda det aktivitetsbaserade asynkrona mönstret. Mer information om asynkrona strömmar finns i självstudiekursen Asynkrona strömmar.

Typ av en iterationsvariabel

Använd nyckelordetvar för att låta kompilatorn härleda typen av en iterationsvariabel i -instruktionenforeach, som följande kod visar:

foreach (var item in collection) { }

Anmärkning

Kompilatorn kan härleda typen av en var deklaration som en nullbar referenstyp, beroende på om den nullbara medvetna kontexten är aktiverad och om typen av ett initieringsuttryck är en referenstyp. Mer information finns i Implicit skrivna lokala variabler.

Du kan också uttryckligen ange typen av en iterationsvariabel, som följande kod visar:

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

I föregående formulär måste typen T av ett samlingselement implicit eller explicit konverteras till typen V av en iterationsvariabel. Om en explicit konvertering från T till V misslyckas vid körningen genererar -instruktionen foreach en InvalidCastException. Om T till exempel är en icke-förseglad klasstyp V kan vara vilken gränssnittstyp som helst, även den som T inte implementeras. Vid körning kan typen av ett samlingselement vara den som härleds från T och faktiskt implementerar V. Om så inte är fallet, utlöses en InvalidCastException.

Påståendet do

-instruktionen do kör en instruktion eller ett block med -instruktioner medan ett angivet booleskt uttryck utvärderas till true. Eftersom loopen utvärderar uttrycket efter varje körning körs en do loop en eller flera gånger. Loopen do skiljer sig från loopenwhile, som kör noll eller fler gånger.

I följande exempel visas användningen av do-instruktionen:

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

Påståendet while

-instruktionen while kör en instruktion eller ett block med -instruktioner medan ett angivet booleskt uttryck utvärderas till true. Eftersom loopen utvärderar uttrycket före varje körning körs en while loop noll eller fler gånger. Loopen while skiljer sig från loopendo, som körs en eller flera gånger.

I följande exempel visas användningen av while-instruktionen:

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

Språkspecifikation för C#

Mer information finns i följande avsnitt i C#-språkspecifikationen:

Se även