Partager via


Procédure pas à pas : implémentation d’IEnumerable(Of T) dans Visual Basic

L’interface IEnumerable<T> est implémentée par des classes qui peuvent retourner une séquence de valeurs d’un élément à la fois. L’avantage de traiter les données un élément à la fois est que vous n’avez pas besoin de charger l’ensemble complet des données en mémoire pour les utiliser. Vous devez uniquement utiliser suffisamment de mémoire pour charger un seul élément à partir des données. Les classes qui implémentent l’interface IEnumerable(T) peuvent être utilisées avec For Each boucles ou requêtes LINQ.

Par exemple, considérez une application qui doit lire un fichier texte volumineux et renvoyer chaque ligne du fichier qui correspond à des critères de recherche particuliers. L’application utilise une requête LINQ pour retourner 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 consomme 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, en retournant uniquement les valeurs qui correspondent aux critères de recherche. Les requêtes qui retournent seulement 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 au sein des données sources. Ces deux classes vous permettent de retourner des éléments de données de manière séquentielle en tant que type spécifique.

Dans cette procédure pas à pas, vous allez 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 d’une ligne à la fois.

Remarque

Votre ordinateur peut afficher différents noms ou emplacements pour certains des éléments de l’interface utilisateur Visual Studio dans les instructions suivantes. L’édition Visual Studio que vous avez et les paramètres que vous utilisez déterminent ces éléments. Pour plus d’informations, consultez Personnaliser l’IDE.

Création de la classe Enumerable

Créer le projet de classe énumérable

  1. Dans Visual Basic, dans le menu Fichier , pointez sur Nouveau , puis cliquez sur Projet.

  2. 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.

  3. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le fichier Class1.vb, puis cliquez sur Renommer. Renommez le fichier StreamReaderEnumerable.vb et appuyez sur Entrée. Le changement de nom du fichier renommera également la classe en StreamReaderEnumerable. Cette classe implémente l’interface IEnumerable(Of String) .

  4. Cliquez avec le bouton droit sur le projet StreamReaderEnumerable, pointez sur Ajouter, puis cliquez sur Nouvel élément. Sélectionnez le modèle de classe . Dans la zone Nom , tapez 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 implémente l’interface IEnumerable et garantit que les consommateurs de cette classe peuvent accéder aux valeurs typées en tant que String.

Ajouter le code pour implémenter IEnumerable

  1. Ouvrez le fichier StreamReaderEnumerable.vb.

  2. Sur la ligne après Public Class StreamReaderEnumerable, tapez ce qui suit et appuyez sur Entrée.

    Implements IEnumerable(Of String)
    

    Visual Basic remplit automatiquement la classe avec les membres requis par l’interface IEnumerable(Of String) .

  3. Cette classe énumérable lit les lignes d’un fichier texte d’une ligne à la fois. Ajoutez le code suivant à la classe pour exposer un constructeur public qui prend un chemin d’accès de fichier en tant que paramètre d’entrée.

    Private _filePath As String
    
    Public Sub New(ByVal filePath As String)
        _filePath = filePath
    End Sub
    
  4. Votre implémentation de la GetEnumerator méthode de l’interface IEnumerable(Of String) retourne une nouvelle instance de la StreamReaderEnumerator classe. L’implémentation de la GetEnumerator méthode de l’interface IEnumerable peut être effectuée Private, car vous devez exposer uniquement les membres de l’interface IEnumerable(Of String) . Remplacez le code généré par Visual Basic pour les GetEnumerator 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

  1. Ouvrez le fichier StreamReaderEnumerator.vb.

  2. Sur la ligne après Public Class StreamReaderEnumerator, tapez ce qui suit et appuyez sur Entrée.

    Implements IEnumerator(Of String)
    

    Visual Basic remplit automatiquement la classe avec les membres requis par l’interface IEnumerator(Of String) .

  3. La classe d’é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 d’accès de fichier en tant que paramètre d’entrée et ouvrez le fichier texte pour la lecture.

    Private _sr As IO.StreamReader
    
    Public Sub New(ByVal filePath As String)
        _sr = New IO.StreamReader(filePath)
    End Sub
    
  4. Les propriétés Current des interfaces IEnumerator(Of String) et IEnumerator renvoient l’élément courant à partir du fichier texte sous la forme d’un String. L’implémentation de la Current propriété de l’interface IEnumerator peut être effectuée Private, car vous devez exposer uniquement les membres de l’interface IEnumerator(Of String) . Remplacez le code généré par Visual Basic pour les Current 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
    
  5. La MoveNext méthode de l’interface IEnumerator accède à l’élément suivant dans le fichier texte et met à jour la valeur retournée par la Current propriété. S’il n’y a plus d’éléments à lire, la MoveNext méthode retourne False; sinon, la MoveNext méthode renvoie True. Ajoutez le code suivant à la méthode MoveNext .

    Public Function MoveNext() As Boolean _
        Implements System.Collections.IEnumerator.MoveNext
    
        _current = _sr.ReadLine()
        If _current Is Nothing Then Return False
        Return True
    End Function
    
  6. La Reset méthode de l’interface IEnumerator dirige l’itérateur vers le début du fichier texte et efface la valeur de l’élément actuel. Ajoutez le code suivant à la méthode Reset .

    Public Sub Reset() _
        Implements System.Collections.IEnumerator.Reset
    
        _sr.DiscardBufferedData()
        _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin)
        _current = Nothing
    End Sub
    
  7. La Dispose méthode de l’interface IEnumerator 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’objet StreamReader est une ressource non managée et doit être fermé avant la destruction de l’instance d’itérateur. Remplacez le code généré par Visual Basic pour la Dispose méthode 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’itérateur d’exemple

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, tel qu’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()

Voir aussi