Iterationsinstruktioner – for
, foreach
, do
och while
Iterationsinstruktionerna kör upprepade gånger en instruktion eller ett block med instruktioner. -instruktionen for
kör dess brödtext medan ett angivet booleskt uttryck utvärderas till .true
-instruktionen foreach
räknar upp elementen i en samling och kör dess brödtext för varje element i samlingen. Instruktionen do
kör villkorligt dess brödtext en eller flera gånger. Instruktionen while
kör villkorsstyrt dess brödtext noll eller fler gånger.
När som helst i en iterationsuttrycks brödtext kan du bryta dig ur loopen med hjälp av -instruktionenbreak
. Du kan gå till nästa iteration i loopen med hjälp av -instruktionencontinue
.
Instruktionen 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ör dess brödtext 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 -instruktionen for
:
Initieringsavsnittet som bara körs en gång innan du anger loopen. Vanligtvis deklarerar och initierar du en lokal loopvariabel i det avsnittet. Den deklarerade variabeln kan inte nås 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:
- prefix eller postfix-inkrementsuttryck, till exempel
++i
elleri++
- prefix eller postfix decrementuttryck , till exempel
--i
elleri--
- Tilldelning
- anrop av en metod
await
Uttryck- skapa ett objekt med hjälp av operatorn
new
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 -instruktionen for
är valfria. Följande kod definierar till exempel den oändliga for
loopen:
for ( ; ; )
{
//...
}
Instruktionen 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. MetodenGetEnumerator
kan vara en typs tilläggsmetod. - Returtypen för
GetEnumerator
metoden har den offentligaCurrent
egenskapen och den offentliga parameterlösaMoveNext
metoden vars returtyp ärbool
.
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 referensreturvärde ( där är typen av ett samlingselementCurrent
) kan du deklarera en iterationsvariabel med ref
eller ref readonly
modifieraren, som följande exempel visar:T
ref T
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 -instruktionen foreach
tillämpas på null
genereras en NullReferenceException .
await foreach
Du kan använda -instruktionen await foreach
för att använda en asynkron dataström, dvs. den 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 metoden kan vara en typs tilläggsmetod. - Returtypen för
GetAsyncEnumerator
metoden har den offentligaCurrent
egenskapen och den offentliga parameterlösaMoveNextAsync
metoden vars returtyp ärTask<bool>
,ValueTask<bool>
eller någon annan väntande typ varsGetResult
awaiter-metod returnerar ettbool
värde.
Som standard bearbetas dataströ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
Du kan använda nyckelordet var
för att låta kompilatorn härleda typen av en iterationsvariabel i -instruktionenforeach
, som följande kod visar:
foreach (var item in collection) { }
Kommentar
Typ av var
kan härledas av kompilatorn 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 .
Instruktionen do
-instruktionen do
kör en instruktion eller ett block med -instruktioner medan ett angivet booleskt uttryck utvärderas till true
. Eftersom uttrycket utvärderas efter varje körning av loopen 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 -instruktionen do
:
int n = 0;
do
{
Console.Write(n);
n++;
} while (n < 5);
// Output:
// 01234
Instruktionen while
-instruktionen while
kör en instruktion eller ett block med -instruktioner medan ett angivet booleskt uttryck utvärderas till true
. Eftersom uttrycket utvärderas före varje körning av loopen 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 -instruktionen while
:
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:
Mer information om dessa funktioner finns i följande kommentarer om funktionsförslag: