Procédure pas à pas : implémentation d'IEnumerable(Of T) en Visual Basic
L’interface IEnumerable<T> est implémentée par des classes qui peuvent retourner une séquence de valeurs un élément à la fois. L’avantage de retourner des données un élément à la fois est que vous n’avez pas besoin de charger l’ensemble complet de données en mémoire pour l’utiliser. Il suffit d'utiliser suffisamment de mémoire pour charger un seul élément des données. Les classes qui implémentent l’interface IEnumerable(T)
peuvent être utilisées avec For Each
des boucles ou des requêtes LINQ.
Par exemple, considérez une application qui doit lire un fichier texte volumineux et retourner chaque ligne du fichier qui correspond à des critères de recherche particuliers. L’application utilise une requête LINQ pour renvoyer des lignes du fichier qui correspondent aux critères spécifiés. Pour interroger le contenu du fichier à l'aide d'une requête LINQ, l'application peut charger le contenu du fichier dans un tableau ou une collection. Toutefois, le chargement du fichier entier dans un tableau ou une collection consommerait beaucoup plus de mémoire que nécessaire. La requête LINQ peut plutôt interroger le contenu du fichier à l’aide d’une classe énumérable, renvoyant uniquement les valeurs qui correspondent aux critères de recherche. Les requêtes qui ne renvoient que quelques valeurs correspondantes consomment beaucoup moins de mémoire.
Vous pouvez créer une classe qui implémente l’interface IEnumerable<T> pour exposer les données sources en tant que données énumérables. Votre classe qui implémente l’interface IEnumerable(T)
nécessite une autre classe qui implémente l’interface IEnumerator<T> pour itérer dans les données sources. Ces deux classes vous permettent de renvoyer des éléments de données de manière séquentielle selon un type spécifique.
Montre comment créer une classe qui implémente l’interface IEnumerable(Of String)
et une classe qui implémente l’interface IEnumerator(Of String)
pour lire un fichier texte ligne par ligne.
Notes
Il est possible que pour certains des éléments de l'interface utilisateur de Visual Studio, votre ordinateur affiche des noms ou des emplacements différents de ceux indiqués dans les instructions suivantes. L'édition de Visual Studio dont vous disposez et les paramètres que vous utilisez déterminent ces éléments. Pour plus d’informations, consultez Personnalisation de l’IDE.
Création de la classe Énumérable
Créer le projet de classe énumérable
Dans Visual Studio, dans le menu Fichier,pointez sur Nouveau, puis cliquez sur Projet.
Dans la boîte de dialogue Nouveau projet, dans le volet Types de projets, vérifiez que Windows est sélectionné. Sélectionnez Bibliothèque de classes dans le volet Modèles. Dans la zone Nom, tapez
StreamReaderEnumerable
, puis cliquez sur OK. Le nouveau projet s’affiche.Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le fichier Class1.cs, puis cliquez sur Renommer. Renommez le fichier
StreamReaderEnumerable.vb
et appuyez sur Entrée. Quand vous renommez le fichier, la classe est également renomméeStreamReaderEnumerable
. Cette classe va implémenter l’interfaceIEnumerable(Of String)
.Cliquez avec le bouton droit de la souris sur le projet StreamReaderEnumerable, pointez sur Ajouter , puis cliquez sur Nouvel élément. Sélectionnez le modèle Classe . Dans la zone Name (Nom), entrez
StreamReaderEnumerator.vb
et cliquez sur OK.
La première classe de ce projet est la classe énumérable et implémente l’interface IEnumerable(Of String)
. Cette interface générique met en œuvre IEnumerablel'interface et garantit que les consommateurs de cette classe peuvent accéder aux valeurs typées comme String
.
Ajouter le code pour implémenter IEnumerable
Ouvrez le fichier StreamReaderEnumerable.vb.
Sur la ligne après
Public Class StreamReaderEnumerable
, tapez ce qui suit, puis appuyez sur ENTRÉE.Implements IEnumerable(Of String)
Visual Basic remplit automatiquement la classe avec les membres requis par l’interface
IEnumerable(Of String)
.Cette classe énumérable lit les lignes d’un fichier texte une ligne à la fois. Ajoutez le code suivant à la classe pour exposer un constructeur public qui prend un chemin de fichier comme paramètre d'entrée.
Private _filePath As String Public Sub New(ByVal filePath As String) _filePath = filePath End Sub
Votre implémentation de la méthode GetEnumerator de l'
IEnumerable(Of String)
interface renverra une nouvelle instance de la classeStreamReaderEnumerator
. L’implémentation de laGetEnumerator
méthode de l’interfaceIEnumerable
peut être effectuéePrivate
, car vous devez exposer uniquement les membres de l’interfaceIEnumerable(Of String)
. Remplacez le code généré par Visual Basic pour lesGetEnumerator
méthodes par le code suivant.Public Function GetEnumerator() As IEnumerator(Of String) _ Implements IEnumerable(Of String).GetEnumerator Return New StreamReaderEnumerator(_filePath) End Function Private Function GetEnumerator1() As IEnumerator _ Implements IEnumerable.GetEnumerator Return Me.GetEnumerator() End Function
Ajouter le code pour implémenter IEnumerator
Ouvrez le fichier StreamReaderEnumerable.vb.
Sur la ligne après
Public Class StreamReaderEnumerator
, tapez ce qui suit, puis appuyez sur ENTRÉE.Implements IEnumerator(Of String)
Visual Basic remplit automatiquement la classe avec les membres requis par l'
IEnumerator(Of String)
interface.La classe énumérateur ouvre le fichier texte et effectue l’E/S du fichier pour lire les lignes du fichier. Ajoutez le code suivant à la classe pour exposer un constructeur public qui prend un chemin de fichier comme paramètre d'entrée.
Private _sr As IO.StreamReader Public Sub New(ByVal filePath As String) _sr = New IO.StreamReader(filePath) End Sub
Les
Current
propriétés des interfaces et retournentIEnumerator(Of String)
IEnumerator
l’élément actif du fichier texte en tant queString
. L'implémentation de laCurrent
propriété de l'IEnumerator
interface peut être réaliséePrivate
, car vous ne devez exposer que les membres de l'IEnumerator(Of String)
interface. Remplacez le code généré par Visual Basic pour lesCurrent
propriétés par le code suivant.Private _current As String Public ReadOnly Property Current() As String _ Implements IEnumerator(Of String).Current Get If _sr Is Nothing OrElse _current Is Nothing Then Throw New InvalidOperationException() End If Return _current End Get End Property Private ReadOnly Property Current1() As Object _ Implements IEnumerator.Current Get Return Me.Current End Get End Property
La
MoveNext
méthode de l’interfaceIEnumerator
accède à l’élément suivant dans le fichier texte et met à jour la valeur retournée par laCurrent
propriété . S’il n’y a plus d’éléments à lire, laMoveNext
méthode retourneFalse
; sinon, laMoveNext
méthode retourneTrue
. Ajoutez le code suivant à la méthodeMoveNext
.Public Function MoveNext() As Boolean _ Implements System.Collections.IEnumerator.MoveNext _current = _sr.ReadLine() If _current Is Nothing Then Return False Return True End Function
La
Reset
méthode de l’interfaceIEnumerator
indique à l’itérateur de pointer vers le début du fichier texte et efface la valeur de l’élément actuel. Ajoutez le code suivant à la méthodeReset
.Public Sub Reset() _ Implements System.Collections.IEnumerator.Reset _sr.DiscardBufferedData() _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin) _current = Nothing End Sub
La
Dispose
méthode de l’interfaceIEnumerator
garantit que toutes les ressources non managées sont libérées avant la destruction de l’itérateur. Le handle de fichier utilisé par l’objetStreamReader
est une ressource non managée qui doit être fermé avant la destruction de l’itérateur instance. Remplacez le code généré par Visual Basic pour lesDispose
méthodes par le code suivant.Private disposedValue As Boolean = False Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then ' Dispose of managed resources. End If _current = Nothing _sr.Close() _sr.Dispose() End If Me.disposedValue = True End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overrides Sub Finalize() Dispose(False) End Sub
Utilisation de l’exemple d’itérateur
Vous pouvez utiliser une classe énumérable dans votre code avec des structures de contrôle qui nécessitent un objet qui implémente IEnumerable
, comme une For Next
boucle ou une requête LINQ. L'exemple suivant montre le StreamReaderEnumerable
dans une requête LINQ.
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()