Delen via


Overzicht: IEnumerable(of T) implementeren in Visual Basic

De IEnumerable<T> interface wordt geïmplementeerd door klassen die een reeks waarden één item tegelijk kunnen retourneren. Het voordeel van het retourneren van gegevens één item tegelijk is dat u de volledige set gegevens niet hoeft te laden in het geheugen om ermee te werken. U hoeft slechts voldoende geheugen te gebruiken om één item uit de gegevens te laden. Klassen die de IEnumerable(T) interface implementeren, kunnen worden gebruikt met For Each lussen of LINQ-query's.

Denk bijvoorbeeld aan een toepassing die een groot tekstbestand moet lezen en elke regel moet retourneren uit het bestand dat overeenkomt met bepaalde zoekcriteria. De toepassing gebruikt een LINQ-query om regels te retourneren uit het bestand dat voldoet aan de opgegeven criteria. Als u een query wilt uitvoeren op de inhoud van het bestand met behulp van een LINQ-query, kan de toepassing de inhoud van het bestand laden in een matrix of een verzameling. Het laden van het hele bestand in een matrix of verzameling verbruikt echter veel meer geheugen dan vereist is. De LINQ-query kan in plaats daarvan een query uitvoeren op de bestandsinhoud met behulp van een enumerable-klasse, waarbij alleen waarden worden geretourneerd die voldoen aan de zoekcriteria. Query's die slechts enkele overeenkomende waarden retourneren, verbruiken veel minder geheugen.

U kunt een klasse maken waarmee de IEnumerable<T> interface wordt geïmplementeerd om brongegevens beschikbaar te maken als opsommingsgegevens. Uw klasse die de IEnumerable(T) interface implementeert, vereist een andere klasse die de IEnumerator<T> interface implementeert om de brongegevens te doorlopen. Met deze twee klassen kunt u items van gegevens sequentieel retourneren als een specifiek type.

In deze procedure maakt u een klasse die de IEnumerable(Of String) interface implementeert en een klasse waarmee de IEnumerator(Of String) interface wordt geïmplementeerd om een tekstbestand één regel tegelijk te lezen.

Opmerking

Mogelijk worden op uw computer verschillende namen of locaties weergegeven voor sommige elementen van de Visual Studio-gebruikersinterface in de volgende instructies. De Visual Studio-editie die u hebt en de instellingen die u gebruikt, bepalen deze elementen. Zie Personalizing the IDEvoor meer informatie.

De enumerable-klasse maken

Het enumerable-klasseproject maken

  1. Wijs in Visual Basic in het menu Bestand de optie Nieuw aan en klik vervolgens op Project.

  2. Zorg ervoor dat Windows is geselecteerd in het dialoogvenster Nieuw project in het deelvenster Projecttypen. Selecteer Klassebibliotheek in het deelvenster Sjablonen . Typ en klik op StreamReaderEnumerable in het vak Naam. Het nieuwe project wordt weergegeven.

  3. Klik in Solution Explorer met de rechtermuisknop op het bestand Class1.vb en klik op Naam wijzigen. Wijzig de naam van het bestand in StreamReaderEnumerable.vb en druk op Enter. Als u de naam van het bestand wijzigt, wordt ook de naam van de klasse gewijzigd in StreamReaderEnumerable. Met deze klasse wordt de IEnumerable(Of String) interface geïmplementeerd.

  4. Klik met de rechtermuisknop op het project StreamReaderEnumerable, wijs Toevoegen aan en klik vervolgens op Nieuw item. Selecteer het klassesjabloon. Typ en klik op StreamReaderEnumerator.vb in het vak Naam.

De eerste klasse in dit project is de enumerable klasse en implementeert de IEnumerable(Of String) interface. Deze algemene interface implementeert de IEnumerable interface en garandeert dat consumenten van deze klasse toegang hebben tot waarden die zijn getypt als String.

Voeg de code toe om IEnumerable te implementeren

  1. Open het bestand StreamReaderEnumerable.vb.

  2. Typ het volgende op de regel na Public Class StreamReaderEnumerableen druk op Enter.

    Implements IEnumerable(Of String)
    

    Visual Basic vult de klasse automatisch in met de leden die vereist zijn voor de IEnumerable(Of String) interface.

  3. Deze opsommingsklasse leest regels uit een tekstbestand één regel tegelijk. Voeg de volgende code toe aan de klasse om een openbare constructor beschikbaar te maken die een bestandspad als invoerparameter gebruikt.

    Private _filePath As String
    
    Public Sub New(ByVal filePath As String)
        _filePath = filePath
    End Sub
    
  4. Uw implementatie van de GetEnumerator methode van de IEnumerable(Of String) interface retourneert een nieuw exemplaar van de StreamReaderEnumerator klasse. De implementatie van de GetEnumerator-methode van de IEnumerable-interface kan Private worden gemaakt, omdat u alleen de leden van de IEnumerable(Of String)-interface beschikbaar hoeft te stellen. Vervang de code die Visual Basic voor de GetEnumerator methoden heeft gegenereerd door de volgende code.

    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
    

De code toevoegen om IEnumerator te implementeren

  1. Open het StreamReaderEnumerator.vb-bestand.

  2. Typ het volgende op de regel na Public Class StreamReaderEnumeratoren druk op Enter.

    Implements IEnumerator(Of String)
    

    Visual Basic vult de klasse automatisch in met de leden die vereist zijn voor de IEnumerator(Of String) interface.

  3. De enumerator-klasse opent het tekstbestand en voert de I/O van het bestand uit om de regels uit het bestand te lezen. Voeg de volgende code toe aan de klasse om een openbare constructor beschikbaar te maken die een bestandspad als invoerparameter gebruikt en het tekstbestand opent om te lezen.

    Private _sr As IO.StreamReader
    
    Public Sub New(ByVal filePath As String)
        _sr = New IO.StreamReader(filePath)
    End Sub
    
  4. De Current eigenschappen voor zowel de IEnumerator(Of String) als IEnumerator interfaces retourneren het huidige item uit het tekstbestand als een String. De implementatie van de Current eigenschap van de IEnumerator interface kan Private worden uitgevoerd, omdat u alleen leden van de IEnumerator(Of String) interface moet onthullen. Vervang de code die Visual Basic voor de Current eigenschappen heeft gegenereerd door de volgende code.

    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. De MoveNext methode van de IEnumerator interface gaat naar het volgende item in het tekstbestand en werkt de waarde bij die door de Current eigenschap wordt geretourneerd. Als er geen items meer te lezen zijn, retourneert de MoveNext-methode False; anders retourneert de MoveNext-methode True. Voeg de volgende code toe aan de methode 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. Met Reset de methode van de IEnumerator interface wordt de iterator doorgestuurd naar het begin van het tekstbestand en wordt de huidige itemwaarde gewist. Voeg de volgende code toe aan de methode Reset.

    Public Sub Reset() _
        Implements System.Collections.IEnumerator.Reset
    
        _sr.DiscardBufferedData()
        _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin)
        _current = Nothing
    End Sub
    
  7. De Dispose methode van de IEnumerator interface garandeert dat alle niet-beheerde resources worden vrijgegeven voordat de iterator wordt vernietigd. De bestandsgreep die door het StreamReader object wordt gebruikt, is een niet-beheerde resource en moet worden gesloten voordat het iterator-exemplaar wordt vernietigd. Vervang de code die Visual Basic voor de Dispose methode heeft gegenereerd door de volgende code.

    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
    

De voorbeeld-iterator gebruiken

U kunt een enumerable-klasse in uw code gebruiken samen met besturingsstructuren die een object vereisen dat IEnumerable implementeert, zoals een For Next-lus of een LINQ-query. In het volgende voorbeeld ziet u de StreamReaderEnumerable in een LINQ-query.

Dim adminRequests =
    From line In New StreamReaderEnumerable("..\..\log.txt")
    Where line.Contains("admin.aspx 401")

Dim results = adminRequests.ToList()

Zie ook