Iteratie-instructies - for
, foreach
, en do
while
De iteratie-instructies voeren herhaaldelijk een instructie of een blok instructies uit. De for
instructie voert de hoofdtekst uit terwijl een opgegeven Boole-expressie resulteert in true
. Met foreach
de instructie worden de elementen van een verzameling opgesomd en wordt de hoofdtekst voor elk element van de verzameling uitgevoerd. De do
instructie voert de hoofdtekst een of meer keren voorwaardelijk uit. De while
instructie voert voorwaardelijk de hoofdtekst nul of meer keren uit.
Op elk punt in de hoofdtekst van een iteratie-instructie kunt u de lus verbreken met behulp van de break
instructie. U kunt stap voor stap naar de volgende iteratie in de lus gaan met behulp van de continue
instructie.
De for
instructie
Met de for
instructie wordt een instructie of een blok instructies uitgevoerd terwijl een opgegeven Boole-expressie resulteert in true
. In het volgende voorbeeld ziet u de instructie waarmee de for
hoofdtekst wordt uitgevoerd, terwijl een teller voor gehele getallen kleiner is dan drie:
for (int i = 0; i < 3; i++)
{
Console.Write(i);
}
// Output:
// 012
In het voorgaande voorbeeld ziet u de elementen van de for
instructie:
De initialisatiesectie die slechts eenmaal wordt uitgevoerd, voordat u de lus invoert. Normaal gesproken declareert en initialiseert u een lokale lusvariabele in die sectie. De gedeclareerde variabele kan niet worden geopend van buiten de
for
instructie.De initialisatiesectie in het vorige voorbeeld declareert en initialiseert een tellervariabele voor gehele getallen:
int i = 0
De voorwaardesectie die bepaalt of de volgende iteratie in de lus moet worden uitgevoerd. Als deze evalueert
true
of niet aanwezig is, wordt de volgende iteratie uitgevoerd. Anders wordt de lus afgesloten. De voorwaardesectie moet een Boole-expressie zijn.In de sectie Voorwaarde in het voorgaande voorbeeld wordt gecontroleerd of een tellerwaarde kleiner is dan drie:
i < 3
De iteratorsectie die definieert wat er gebeurt na elke uitvoering van de hoofdtekst van de lus.
In de iteratorsectie in het vorige voorbeeld wordt de teller verhoogd:
i++
De hoofdtekst van de lus, die een instructie of een blok instructies moet zijn.
De iteratorsectie kan nul of meer van de volgende instructieexpressies bevatten, gescheiden door komma's:
- incrementele expressie voor voorvoegsel of voorvoegsel, zoals
++i
ofi++
- voorvoegsel- of voorvoegseldecrementexpressie, zoals
--i
ofi--
- Toewijzing
- aanroepen van een methode
await
Expressie- een object maken met behulp van de
new
operator
Als u geen lusvariabele declareert in de sectie Initializer, kunt u ook nul of meer expressies uit de voorgaande lijst in de sectie Initializer gebruiken. In het volgende voorbeeld ziet u verschillende minder gangbare gebruikswijzen van de initialisatie- en iteratorsecties: het toewijzen van een waarde aan een externe variabele in de initialisatiesectie, het aanroepen van een methode in zowel de initialisatiefunctie als de iterator-secties, en het wijzigen van de waarden van twee variabelen in de iteratorsectie:
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
Alle secties van de for
instructie zijn optioneel. Met de volgende code wordt bijvoorbeeld de oneindige for
lus gedefinieerd:
for ( ; ; )
{
//...
}
De foreach
instructie
Met foreach
de instructie wordt een instructie of een blok instructies uitgevoerd voor elk element in een exemplaar van het type dat de System.Collections.IEnumerable of System.Collections.Generic.IEnumerable<T> interface implementeert, zoals in het volgende voorbeeld wordt weergegeven:
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
De foreach
instructie is niet beperkt tot deze typen. U kunt het gebruiken met een exemplaar van elk type dat voldoet aan de volgende voorwaarden:
- Een type heeft de openbare methode zonder parameters
GetEnumerator
. DeGetEnumerator
methode kan de extensiemethode van een type zijn. - Het retourtype van de
GetEnumerator
methode heeft de openbareCurrent
eigenschap en de openbare parameterlozeMoveNext
methode waarvan het retourtype isbool
.
In het volgende voorbeeld wordt de foreach
instructie gebruikt met een exemplaar van het System.Span<T> type, waarmee geen interfaces worden geïmplementeerd:
Span<int> numbers = [3, 14, 15, 92, 6];
foreach (int number in numbers)
{
Console.Write($"{number} ");
}
// Output:
// 3 14 15 92 6
Als de eigenschap van Current
de enumerator een retourwaarde retourneert (ref T
waar T
is het type verzamelingselement), kunt u een iteratievariabele declareren met de ref
of ref readonly
modifier, zoals in het volgende voorbeeld wordt weergegeven:
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
Als de bronverzameling van de foreach
instructie leeg is, wordt de hoofdtekst van de foreach
instructie niet uitgevoerd en overgeslagen. Als de foreach
instructie wordt toegepast op null
, wordt er een NullReferenceException gegenereerd.
wachten op foreach
U kunt de await foreach
instructie gebruiken om een asynchrone gegevensstroom te gebruiken, dat wil zeggen het verzamelingstype waarmee de IAsyncEnumerable<T> interface wordt geïmplementeerd. Elke iteratie van de lus kan worden onderbroken terwijl het volgende element asynchroon wordt opgehaald. In het volgende voorbeeld ziet u hoe u de await foreach
instructie gebruikt:
await foreach (var item in GenerateSequenceAsync())
{
Console.WriteLine(item);
}
U kunt de await foreach
instructie ook gebruiken met een exemplaar van elk type dat voldoet aan de volgende voorwaarden:
- Een type heeft de openbare methode zonder parameters
GetAsyncEnumerator
. Deze methode kan de extensiemethode van een type zijn. - Het retourtype van de
GetAsyncEnumerator
methode heeft de openbareCurrent
eigenschap en de openbare parameterlozeMoveNextAsync
methode waarvan het retourtype isTask<bool>
,ValueTask<bool>
of een ander te wachtend type waarvan de methode vanGetResult
de wachter eenbool
waarde retourneert.
Stream-elementen worden standaard verwerkt in de vastgelegde context. Als u het vastleggen van de context wilt uitschakelen, gebruikt u de TaskAsyncEnumerableExtensions.ConfigureAwait extensiemethode. Zie Het gebruik van het asynchrone patroon op basis van taken voor meer informatie over synchronisatiecontexten en het vastleggen van de huidige context. Zie de zelfstudie Asynchrone streams voor meer informatie over asynchrone streams.
Type iteratievariabele
U kunt het var
trefwoord gebruiken om het type iteratievariabele in de foreach
instructie te laten afleiden door de compiler, zoals in de volgende code wordt weergegeven:
foreach (var item in collection) { }
Notitie
var
Het type kan worden afgeleid door de compiler als een null-referentietype, afhankelijk van of de context nullable is ingeschakeld en of het type initialisatie-expressie een verwijzingstype is.
Zie Impliciet getypte lokale variabelen voor meer informatie.
U kunt ook expliciet het type iteratievariabele opgeven, zoals in de volgende code wordt weergegeven:
IEnumerable<T> collection = new T[5];
foreach (V item in collection) { }
In het voorgaande formulier moet het type T
verzamelingselement impliciet of expliciet worden omgezet in het type V
iteratievariabele. Als een expliciete conversie van T
naar V
runtime mislukt, genereert de foreach
instructie een InvalidCastException. Als dit bijvoorbeeld T
een niet-verzegeld klassetype is, V
kan elk interfacetype zijn, zelfs het type dat T
niet wordt geïmplementeerd. Tijdens runtime kan het type verzamelingselement het element zijn dat is afgeleid van T
en daadwerkelijk implementeert V
. Als dat niet het geval is, wordt er een InvalidCastException gegooid.
De do
instructie
Met de do
instructie wordt een instructie of een blok instructies uitgevoerd terwijl een opgegeven Boole-expressie resulteert in true
. Omdat deze expressie wordt geëvalueerd na elke uitvoering van de lus, wordt een of meer keren uitgevoerd do
. De do
lus verschilt van de while
lus, die nul of meer keer wordt uitgevoerd.
In het volgende voorbeeld ziet u het gebruik van de do
instructie:
int n = 0;
do
{
Console.Write(n);
n++;
} while (n < 5);
// Output:
// 01234
De while
instructie
Met de while
instructie wordt een instructie of een blok instructies uitgevoerd terwijl een opgegeven Boole-expressie resulteert in true
. Omdat deze expressie wordt geëvalueerd voordat elke uitvoering van de lus wordt uitgevoerd, wordt een while
lus nul of meer keren uitgevoerd. De while
lus verschilt van de do
lus, die een of meer keren wordt uitgevoerd.
In het volgende voorbeeld ziet u het gebruik van de while
instructie:
int n = 0;
while (n < 5)
{
Console.Write(n);
n++;
}
// Output:
// 01234
C#-taalspecificatie
Zie de volgende secties van de C#-taalspecificatie voor meer informatie:
Zie de volgende opmerkingen over functievoorstel voor meer informatie over deze functies: