Partager via


Instructions d’itération - for, foreach, doet while

Les instructions d’itération exécutent à plusieurs reprises une instruction ou un bloc d’instructions. L’instruction for exécute son corps tant qu’une expression booléenne spécifiée renvoie true. L'instructionforeach énumère les éléments d'une collection et exécute son bloc d'instructions pour chaque élément de la collection. L’instruction do exécute son corps une ou plusieurs fois de manière conditionnelle. L’instruction while exécute son corps zéro ou plusieurs fois de manière conditionnelle.

À tout moment dans le corps d’une instruction d’itération, vous pouvez sortir de la boucle à l’aide de l’instructionbreak. Vous pouvez passer à l’itération suivante dans la boucle à l’aide de l’instructioncontinue.

L’instruction for.

L’instruction for exécute une instruction ou un bloc d’instructions pendant qu’une expression booléenne spécifiée prend truela valeur . L’exemple suivant montre l’instruction for qui exécute son corps alors qu’un compteur entier est inférieur à trois :

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

L’exemple précédent montre les éléments de l’instruction for :

  • Section initialiseur exécutée une seule fois, avant d’entrer dans la boucle. En règle générale, vous déclarez et initialisez une variable de boucle locale dans cette section. La variable déclarée n’est pas accessible à partir de l’extérieur de l’instruction for .

    La section initialiseur de l’exemple précédent déclare et initialise une variable de compteur entier :

    int i = 0
    
  • Section de condition qui détermine si l’itération suivante de la boucle doit être exécutée. Si elle est évaluée à true ou n’est pas présente, l’itération suivante est exécutée ; sinon, la boucle est quittée. La section condition doit être une expression booléenne.

    La section condition de l’exemple précédent vérifie si une valeur de compteur est inférieure à trois :

    i < 3
    
  • Section itérateur qui définit ce qui se passe après chaque exécution du corps de la boucle.

    La section itérateur de l’exemple précédent incrémente le compteur :

    i++
    
  • Le corps de la boucle, qui doit être une instruction ou un bloc d’instructions.

La section itérateur peut contenir zéro, une ou plusieurs des expressions d’instruction suivantes, séparées par des virgules :

Si vous ne déclarez pas de variable de boucle dans la section initialiseur, vous pouvez également utiliser zéro ou plusieurs expressions de la liste précédente dans la section initialiseur. L’exemple suivant montre plusieurs utilisations moins courantes des sections initialiseur et itérateur : affectation d’une valeur à une variable externe dans la section initialiseur, appel d’une méthode dans les sections initialiseur et itérateur, et modification des valeurs de deux variables dans la section itérateur :

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

Toutes les sections de l’instruction for sont facultatives. Par exemple, le code suivant définit la boucle infinie for :

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

L’instruction foreach.

L'instruction foreach exécute une instruction ou un bloc d'instructions pour chaque élément d'une instance du type qui implémente l'interface System.Collections.IEnumerable ou l'interface System.Collections.Generic.IEnumerable<T>, comme l'illustre l'exemple suivant :

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

L’instruction foreach n’est pas limitée à ces types. Vous pouvez l’utiliser avec une instance de n’importe quel type qui répond aux conditions suivantes :

  • Un type a une méthode publique sans paramètre GetEnumerator. La GetEnumerator méthode peut être la méthode d’extension d’un type.
  • Le type de retour de la méthode GetEnumerator comprend la propriété publique Current et la méthode publique sans paramètre MoveNext dont le type de retour est bool.

L’exemple suivant utilise l’instruction foreach avec une instance du System.Span<T> type, qui n’implémente aucune interface :

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

Si la propriété de l’énumérateur Current retourne une valeur de retour de référence (ref TT est le type d’un élément de collection), vous pouvez déclarer une variable d’itération avec le ref ou le ref readonly modificateur, comme l’illustre l’exemple suivant :

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

Si la collection source de l’instruction foreach est vide, le corps de l’instruction foreach n’est pas exécuté et ignoré. Si l’instruction foreach est appliquée à null, une NullReferenceException est lancée.

await foreach

Vous pouvez utiliser l’instruction await foreach pour consommer un flux asynchrone de données, autrement dit, le type de collection qui implémente l’interface IAsyncEnumerable<T> . Chaque itération de la boucle peut être suspendue pendant que l’élément suivant est récupéré de façon asynchrone. L’exemple suivant montre comment utiliser l’instruction await foreach :

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

Vous pouvez également utiliser l’instruction await foreach avec une instance de n’importe quel type qui répond aux conditions suivantes :

  • Un type a une méthode publique sans paramètre GetAsyncEnumerator. Cette méthode peut être la méthode d’extension d’un type.
  • Le type de retour de la méthode GetAsyncEnumerator a la propriété publique Current et la méthode publique sans paramètre MoveNextAsync dont le type de retour est Task<bool>, ValueTask<bool>, ou tout autre type awaitable dont l'awaiter a une méthode GetResult qui retourne une valeur bool.

Par défaut, les éléments de flux sont traités dans le contexte capturé. Si vous souhaitez désactiver la capture du contexte, utilisez la TaskAsyncEnumerableExtensions.ConfigureAwait méthode d’extension. Pour plus d’informations sur les contextes de synchronisation et la capture du contexte actuel, consultez Consommation du modèle asynchrone basé sur les tâches. Pour plus d’informations sur les flux asynchrones, consultez le didacticiel sur les flux asynchrones.

Type d’une variable d’itération

Vous pouvez utiliser le var mot clé pour laisser le compilateur déduire le type d’une variable d’itération dans l’instruction foreach , comme le montre le code suivant :

foreach (var item in collection) { }

Remarque

Le type de var peut être déduit par le compilateur en tant que type de référence nullable, selon que le contexte conscient des nullables est activé et si le type d'une expression d'initialisation est un type de référence. Pour plus d’informations, consultez Variables locales implicitement typées.

Vous pouvez également spécifier explicitement le type d’une variable d’itération, comme le montre le code suivant :

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

Dans le formulaire précédent, le type T d’un élément de collection doit être implicitement ou explicitement convertible en type V d’une variable d’itération. Si une conversion explicite de T à V échoue au moment de l'exécution, l’instruction foreach lève un InvalidCastException. Par exemple, s’il s’agit T d’un type de classe non scellé, V peut être n’importe quel type d’interface, même celui qui T n’implémente pas. Au moment de l’exécution, le type d’un élément de collection peut être celui qui dérive de T et implémente réellement V. Si ce n’est pas le cas, une InvalidCastException est levée.

L’instruction do.

L’instruction do exécute une instruction ou un bloc d’instructions pendant qu’une expression booléenne spécifiée prend truela valeur . Étant donné que cette expression est évaluée après chaque exécution de la boucle, une do boucle s’exécute une ou plusieurs fois. La do boucle diffère de la while boucle, qui exécute zéro ou plus de fois.

L’exemple suivant montre l’utilisation de l’instruction do :

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

L’instruction while.

L’instruction while exécute une instruction ou un bloc d’instructions pendant qu’une expression booléenne spécifiée prend truela valeur . Étant donné que cette expression est évaluée avant chaque exécution de la boucle, une while boucle s’exécute zéro ou plusieurs fois. La while boucle diffère de la do boucle, qui exécute une ou plusieurs fois.

L’exemple suivant montre l’utilisation de l’instruction while :

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

Spécification du langage C#

Pour plus d’informations, consultez les sections suivantes de la spécification du langage C# :

  • L’instruction for
  • L’instruction foreach
  • L’instruction do
  • L’instruction while

Pour plus d’informations sur ces fonctionnalités, consultez les notes de proposition des fonctionnalités suivantes :

Voir aussi