Historique de la question
Les itérateurs sont devenus une partie importante des langages de programmation avec l'apparition des collections à parcourir. En Visual Basic, depuis la version .NET, la prise en charge de IEnumerable/IEnumerator est disponible, permettant de mettre en œuvre ses propres collections itérables et d'utiliser la boucle For Each pour un accès pratique et concis au contenu des collections.
Problème
De nombreux développeurs se limitent à l'utilisation uniquement des collections intégrées ou n'implémentent pas correctement l'interface IEnumerable, ce qui rend impossible le parcours des objets via For Each. De plus, la gestion de l'état de l'itérateur à travers Current et MoveNext pose des difficultés.
Solution
Pour prendre en charge les itérations, le type doit implémenter l'interface IEnumerable (ou IEnumerable(Of T) générique). Implémentez la fonction GetEnumerator, retournant un objet implémentant IEnumerator. En VB.NET, des méthodes d'itérateur peuvent également être appliquées avec le mot clé Yield (à partir de VB 2015), ce qui simplifie considérablement l'implémentation du parcours.
Exemple de code:
Imports System.Collections Public Class SimpleCollection Implements IEnumerable Private arr() As Integer = {1, 2, 3} Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator For Each i In arr Yield i ' pour VB 2015+ Next End Function End Class ' Utilisation: For Each n As Integer In New SimpleCollection() Console.WriteLine(n) Next
Caractéristiques clés:
Est-il nécessaire d'implémenter les deux interfaces: IEnumerable et IEnumerator, pour prendre en charge For Each ?
Non, l'implémentation de IEnumerable et le retour d'un itérateur compatible suffisent. Si vous souhaitez implémenter le parcours, vous pouvez utiliser l'IEnumerator existant de la collection imbriquée. Mais pour une personnalisation complète, les deux parties doivent être implémentées.
Exemple de code:
Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return arr.GetEnumerator() ' utilise l'itérateur intégré du tableau End Function
Peut-on implémenter IEnumerable uniquement explicitement (Explicit Interface Implementation) en Visual Basic ?
Oui, on peut implémenter l'interface de manière explicite, surtout si votre collection a déjà son propre GetEnumerator, et que vous souhaitez cacher l'implémentation de l'interface. Appeler un tel GetEnumerator directement ne sera pas possible, mais For Each fonctionnera.
Exemple de code:
Public Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator ' ...corps de méthode End Function
Que se passe-t-il si GetEnumerator retourne Nothing ?
Une exception sera levée lors de la première tentative de parcours de la collection, car For Each s'attend à un itérateur valide.
La classe de collection n'a pas implémenté IEnumerable, et une méthode séparée Next a été créée pour parcourir les éléments. En fin de compte, elle ne peut pas être utilisée dans des méthodes universelles ou For Each, il faut écrire des méthodes supplémentaires.
Avantages :
Inconvénients :
Le développeur a implémenté IEnumerable et GetEnumerator, la collection fonctionne maintenant avec For Each et s'intègre avec LINQ.
Avantages :
Inconvénients :