For Each...Next, instruction (Visual Basic)
Mise à jour : Juillet 2008
Répète un groupe d'instructions pour chaque élément d'une collection.
For Each element [ As datatype ] In group
[ statements ]
[ Exit For ]
[ statements ]
Next [ element ]
Éléments
element
Requis dans l'instruction For Each. Facultatif dans l'instruction Next. Variable. Utilisé pour parcourir tous les éléments d'une collection.datatype
Obligatoire si element n'est pas déjà déclaré. Type de données de element.group
Obligatoire. Variable objet. Fait référence à la collection sur laquelle les statements doivent être répétées.statements
Facultatif. Une ou plusieurs instructions entre For Each et Next qui s'exécutent sur chaque élément dans group.Exit For
Facultatif. Transfert le contrôle hors de la boucle For Each.Next
Obligatoire. Termine la définition de la boucle For Each.
Notes
Utilisez une boucle For Each...Next lorsque vous souhaitez répéter un ensemble d'instructions pour chaque élément d'une collection ou d'un tableau.
Une For...Next, instruction (Visual Basic) fonctionne correctement lorsque vous pouvez associer chaque itération d'une boucle à une variable de contrôle et déterminer les valeurs initiale et finale de cette variable. Toutefois, lorsque vous gérez une collection, le concept de valeurs initiales et finales n'a pas de sens et vous n'êtes pas obligé de connaître le nombre d'éléments que contient la collection. Dans ce cas, une boucle For Each...Next est un meilleur choix.
Règles
Types de données. Le type de données de element doit se présenter de façon telle que le type de données des éléments de group puisse être converti vers lui.
Le type de données de group doit être un type référence qui fait référence à une collection ou à un tableau. Cela signifie que group doit faire référence à un objet qui implémente l'interface IEnumerable de l'espace de noms System.Collections ou l'interface IEnumerable<T> de l'espace de noms System.Collections.Generic. IEnumerable définit la méthode GetEnumerator qui retourne un objet énumérateur pour la collection. L'objet énumérateur implémente l'interface IEnumerator de l'espace de noms System.Collections et expose la propriété Current et les méthodes Reset et MoveNext. Visual Basic les utilise pour parcourir la collection.
Les éléments de group sont généralement de type Object, mais ils peuvent avoir n'importe quel type de données exécutable.
Conversions restrictives. Lorsque Option Strict a la valeur On, les conversions restrictives provoquent ordinairement des erreurs du compilateur. Dans l'exemple suivant, l'affectation de m comme valeur initiale pour n ne se compile pas avec Option Strict activée parce que la conversion d'un Long en Integer est une conversion restrictive.
Dim m As Long = 987 ' Does not compile. 'Dim n As Integer = m
Toutefois, les conversions à partir des éléments dans group jusqu'à element sont évaluées et sont exécutées au moment de l'exécution, et l'erreur de conversion restrictive est supprimée. Dans l'exemple suivant, aucune erreur du compilateur n'est signalée dans la boucle For Each, même si cela nécessite la même conversion de Long à Integer qui a provoqué une erreur dans l'exemple précédent.
Option Strict On Module Module1 Sub Main() ' The assignment of m to n causes a compiler error when ' Option Strict is on. Dim m As Long = 987 'Dim n As Integer = m ' The For Each loop requires the same conversion, but ' causes no errors. The output is 45 3 987. For Each p As Integer In New Long() {45, 3, 987} Console.Write(p & " ") Next Console.WriteLine() End Sub End Module
L'absence d'erreur du compilateur n'élimine pas le risque d'une erreur d'exécution. Dans l'exemple suivant, aucune erreur du compilateur n'est signalée, mais une erreur d'exécution se produit lorsque ToInteger est appliqué à 9876543210. L'erreur d'exécution se produit si Option Strict est activée ou désactivée.
Option Strict On Module Module1 Sub Main() ' The assignment of m to n causes a compiler error when ' Option Strict is on. Dim m As Long = 9876543210 'Dim n As Integer = m Try ' The For Each loop requires the same conversion, but ' is not flagged by the compiler. A run-time error is ' raised because 9876543210 is too large for type Integer. For Each p As Integer In New Long() {45, 3, 9876543210} Console.Write(p & " ") Next Console.WriteLine() Catch e As System.OverflowException Console.WriteLine() Console.WriteLine(e.Message) End Try End Sub End Module
Déclaration. Si la variable element n'a pas été déclarée à l'extérieur de cette boucle, vous devez la déclarer dans l'instruction For Each. Vous pouvez déclarer explicitement le type d'element en utilisant une instruction As ou vous pouvez compter sur l'inférence de type pour assigner le type. Dans les deux cas, la portée de element est le corps de la boucle. Cependant, vous ne pouvez pas déclarer element à la fois à l'extérieur et à l'intérieur de la boucle.
Nombre d'itérations. Visual Basic évalue la collection une seule fois, avant que la boucle ne commence. Si votre bloc d'instructions modifie element ou group, ces modifications n'affectent pas l'itération de la boucle.
Imbrication de boucles. Vous pouvez imbriquer les boucles For Each en plaçant une boucle à l'intérieur d'une autre. Toutefois, chaque boucle doit posséder une variable element unique.
Vous pouvez également imbriquer différents types de structures de contrôle les uns dans les autres. Pour plus d'informations, consultez Structures de contrôle imbriquées.
Remarque : Si une instruction Next d'un niveau d'imbrication externe est rencontrée avant le Next d'un niveau interne, le compilateur signale une erreur. Toutefois, le compilateur peut détecter cette erreur de chevauchement uniquement si vous spécifiez element dans chaque instruction Next.
Identification de la variable de contrôle. Vous pouvez éventuellement définir element dans l'instruction Next. Cela améliore la lisibilité de votre programme, surtout si vous avez imbriqué des boucles For Each. Vous devez spécifier la même variable que celle qui apparaît dans l'instruction For Each correspondante.
Transfert hors de la boucle. L'instruction Exit, instruction (Visual Basic) passe immédiatement le contrôle à l'instruction qui suit l'instruction Next. Vous pouvez éventuellement quitter une boucle si vous décelez une condition qui la rend inutile ou impossible pour poursuivre l'itération, telle qu'une valeur erronée ou une demande d'arrêt. Si vous décelez une exception dans une instruction Try...Catch...Finally, vous pouvez utiliser Exit For à la fin du bloc Finally.
Vous pouvez placer un nombre indéterminé d'instructions Exit For n'importe où dans la boucle For Each. Exit For est souvent utilisé après évaluation d'une certaine condition, par exemple dans une structure If...Then...Else.
Boucles infinies. Vous pouvez utiliser Exit For pour tester une condition qui engendrerait une boucle infinie, c'est-à-dire une boucle qui pourrait s'exécuter de nombreuses fois, voire indéfiniment. Si vous détectez une telle condition, vous pouvez utiliser Exit For pour abandonner la boucle. Pour plus d'informations, consultez Do...Loop, instruction (Visual Basic).
Comportement
Entrée dans la boucle. Lorsque l'exécution de la boucle For Each...Next commence, Visual Basic vérifie que group fait référence à un objet de collection valide. Si tel n'est pas le cas, il lève une exception. Sinon, il appelle la méthode MoveNext et la propriété Current de l'objet énumérateur pour retourner le premier élément. Si MoveNext indique qu'il n'y a aucun élément suivant, c'est-à-dire si la collection est vide, la boucle For Each prend fin et le contrôle est passé à l'instruction qui suit l'instruction Next. Sinon, Visual Basic affecte element au premier élément et exécute le bloc d'instructions.
Itérations de la boucle. Chaque fois que Visual Basic rencontre l'instruction Next, il retourne à l'instruction For Each. Il appelle de nouveau MoveNext et Current pou retourner l'élément suivant et exécute à nouveau le bloc ou termine la boucle selon le résultat. Ce processus continue jusqu'à ce que MoveNext indique qu'il n'y a aucun élément suivant ou qu'une instruction Exit For soit rencontrée.
Arrêts de la boucle. Lorsque tous les éléments de la collection ont été successivement assignés à element, la boucle For Each se termine et le contrôle est passé à l'instruction suivant l'instruction Next.
Modification des valeurs d'itération. Changer la valeur de element quand une boucle est en cours d'exécution rendra la lecture et le débogage de votre code plus difficiles. La modification de la valeur de group n'affecte pas la collection ou ses éléments qui étaient déterminés lorsque la boucle était entrée en premier lieu.
Ordre de parcours. Lorsque vous exécutez une boucle For Each...Next, vous pouvez parcourir la collection via le contrôle de l'objet énumérateur retourné par la méthode GetEnumerator. L'ordre de parcours n'est pas déterminé par Visual Basic, mais par la méthode MoveNext de l'objet énumérateur. Ceci signifie que vous ne pourrez peut-être pas prévoir quel sera le premier élément de la collection retourné dans element ou quel sera l'élément suivant renvoyé après un élément donné.
Si votre code dépend du parcours d'une collection selon un ordre défini, une boucle For Each...Next ne représente pas le meilleur choix, sauf si vous connaissez les caractéristiques de l'objet énumérateur exposé par la collection. Vous pouvez obtenir des résultats plus fiables à l'aide d'une structure de boucle différente, par exemple For...Next ou Do...Loop.
Modification de la collection. L'objet énumérateur retourné par GetEnumerator ne vous permet normalement pas de modifier la collection par l'ajout, la suppression, le remplacement ou la réorganisation d'éléments. Si vous modifiez la collection après avoir lancé une boucle For Each...Next, l'objet énumérateur devient non valide et la tentative d'accès suivante à un élément provoque une exception InvalidOperationException.
Toutefois, ce blocage de modification n'est pas déterminé parVisual Basic, mais plutôt par l'implémentation de l'interface IEnumerable. Il est possible d'implémenter IEnumerable de sorte que les modifications soient autorisées pendant l'itération. Si vous comptez effectuer des modifications dynamiques de ce type, soyez sûr que vous connaissez les caractéristiques de l'implémentation de IEnumerable sur la collection que vous utilisez.
Modification d'éléments de collection. La propriété Current de l'objet énumérateur est ReadOnly (Visual Basic). Elle retourne une copie locale de chaque élément de la collection. Cela signifie que vous ne pouvez pas modifier les éléments d'une boucle For Each...Next. Toute modification effectuée n'a d'incidence que sur la copie locale basée sur Current et n'est pas répercutée dans la collection sous-jacente. Cependant, si un élément correspond à un type référence, vous pouvez modifier les membres de l'instance vers laquelle il pointe. L'exemple suivant illustre ce comportement :
Sub lightBlueBackground(ByVal thisForm As System.Windows.Forms.Form) For Each thisControl As System.Windows.Forms.Control In thisForm.Controls thisControl.BackColor = System.Drawing.Color.LightBlue Next thisControl End Sub
L'exemple précédent peut modifier le membre BackColor de chaque élément thisControl, bien qu'il ne puisse pas modifier thisControl lui-même.
Parcours de tableaux. Étant donné que la classe Array implémente l'interface IEnumerable, tous les tableaux exposent la méthode GetEnumerator. Cela signifie que vous pouvez parcourir un tableau avec une boucle For Each...Next. Toutefois, vous pouvez uniquement lire les éléments du tableau, et non les modifier. Pour une illustration, consultez Comment : exécuter plusieurs instructions pour chaque élément dans une collection ou un tableau.
Exemple
L'exemple suivant utilise l'instruction For Each...Next pour rechercher tous les éléments de la chaîne dans une collection "Hello". L'exemple suppose que la collection thisCollection a déjà été créée et que ses éléments sont de type String.
Dim found As Boolean = False
Dim thisCollection As New Collection
For Each thisObject As String In thisCollection
If thisObject = "Hello" Then
found = True
Exit For
End If
Next thisObject
Voir aussi
Tâches
Comment : exécuter plusieurs instructions pour chaque élément dans une collection ou un tableau
Comment : améliorer les performances d'une boucle
Concepts
Conversions étendues et restrictives
Référence
While...End While, instruction (Visual Basic)
Do...Loop, instruction (Visual Basic)
Historique des modifications
Date |
Historique |
Raison |
---|---|---|
Juillet 2008 |
Ajout d'une section relative aux conversions restrictives. |
Commentaires client. |