ProgrammationDéveloppeur VB.NET

Décrivez comment fonctionne la boucle For...Each...Next en Visual Basic avec des collections personnalisées. Comment créer votre propre collection pour parcourir avec For Each et que devez-vous implémenter ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Histoire de la question :

L'instruction For Each...Next en Visual Basic permet de parcourir les éléments des collections ou des tableaux. À partir de VB6, le parcours des collections standard était supporté, et dans VB.NET, pour tous les types qui implémentent une interface spécifique. Mais quand il s'agit de créer des collections utilisateurs pour un parcours personnalisé, il est important d'implémenter correctement l'infrastructure requise.

Problème

Il ne suffit pas d'implémenter le stockage des éléments — les instructions For Each nécessitent le soutien d'une interface spécialisée IEnumerable. Souvent, la création de collections personnalisées se limitait aux méthodes Add/Get, l'objet devenant une "boîte noire" pour l'itération. Cela empêchait l'intégration avec la structure de parcours du langage et entraînait des erreurs.

Solution

Pour que For Each fonctionne correctement avec votre collection, il est nécessaire d'implémenter l'interface IEnumerable, et pour prendre en charge le travail avec des éléments typés — IEnumerable(Of T). Il faut également créer un énumérateur (Enumerator) personnalisé qui implémente l'interface IEnumerator (ou IEnumerator(Of T) dans les versions génériques).

Exemple:

Public Class IntCollection Implements IEnumerable(Of Integer) Private ReadOnly items As New List(Of Integer)() Public Sub Add(value As Integer) items.Add(value) End Sub Public Function GetEnumerator() As IEnumerator(Of Integer) _ Implements IEnumerable(Of Integer).GetEnumerator Return items.GetEnumerator() End Function Private Function IEnumerable_GetEnumerator() As IEnumerator _ Implements IEnumerable.GetEnumerator Return GetEnumerator() End Function End Class ' Utilisation : Dim col As New IntCollection() col.Add(10) col.Add(20) col.Add(30) For Each n As Integer In col Console.WriteLine(n) Next

Caractéristiques clés :

  • Nécessite l'implémentation des méthodes GetEnumerator et le retour de IEnumerator ou IEnumerator(Of T).
  • Support de IEnumerable générique et non générique pour la compatibilité avec différentes versions de l'environnement.
  • La collection prête peut participer à LINQ, For Each et travailler avec l'infrastructure standard .NET.

Questions piégeuses.

Peut-on implémenter For Each sans l'interface IEnumerable, simplement en écrivant une méthode GetEnumerator ?

Non, Visual Basic nécessite le soutien officiel de l'interface IEnumerable/IEnumerable(Of T) pour que le compilateur reconnaisse la collection comme compatible avec For Each.

L'énumérateur doit-il être une classe distincte ?

Non, si la base de données des éléments prend en charge l'énumérateur standard (par exemple, si vous agrégerez List(Of T)), vous pouvez retourner son GetEnumerator. Ce n'est que dans des scénarios complexes qu'un propre classe implémentant IEnumerator peut être nécessaire.

Est-il possible de modifier la collection à l'intérieur de la boucle For Each ?

Non, la modification de la collection pendant l'itération entraînera une InvalidOperationException. Pour un traitement correct, des stratégies spéciales sont nécessaires (par exemple, copier la liste avant l'itération ou utiliser l'indexation).

Erreurs typiques et anti-patterns

  • Implémentation seulement de Add/Remove sans IEnumerable — impossible d'utiliser For Each.
  • Retour de Enumerator inexistant ou incorrect — entraîne des défaillances pendant le parcours.
  • Modification de la collection dans le corps de la boucle For Each.

Exemple de vie

Cas négatif

Dans l'entreprise, une classe MyCollection a été développée avec ajout et suppression via un tableau, mais sans implémenter l'interface IEnumerable. For Each ne fonctionnait pas, il fallait utiliser des boucles ordinaires et un champ public avec des éléments.

Avantages :

  • Création rapide de la collection — peu de code.

Inconvénients :

  • Impossible d'utiliser For Each, LINQ, impossible de travailler avec comme avec des collections standard.
  • Du code de parcours en double est apparu à différents endroits.

Cas positif

La classe a été refondue, en implémentant IEnumerable(Of T). Après cela, la collection a pu être utilisée facilement et de manière standard avec For Each, et est devenue compatible avec LINQ.

Avantages :

  • Syntaxe propre et standard.
  • Le parcours de la collection est compatible avec toutes les possibilités d'infrastructure de VB.NET.

Inconvénients :

  • Nécessite d'ajouter plus de code pour supporter les interfaces.