Freigeben über


Exemplarische Vorgehensweise: Implementieren von IEnumerable(Of T) in Visual Basic

Die IEnumerable<T> Schnittstelle wird von Klassen implementiert, die jeweils eine Folge von Werten zurückgeben können. Der Vorteil, daten einzeln zurückzugeben, besteht darin, dass Sie nicht den vollständigen Satz von Daten in den Arbeitsspeicher laden müssen, um damit zu arbeiten. Sie müssen nur ausreichend Arbeitsspeicher verwenden, um ein einzelnes Element aus den Daten zu laden. Klassen, die die IEnumerable(T) Schnittstelle implementieren, können mit For Each Schleifen oder LINQ-Abfragen verwendet werden.

Betrachten Sie beispielsweise eine Anwendung, die eine große Textdatei lesen muss, und geben Sie jede Zeile aus der Datei zurück, die bestimmten Suchkriterien entspricht. Die Anwendung verwendet eine LINQ-Abfrage, um Zeilen aus der Datei zurückzugeben, die den angegebenen Kriterien entsprechen. Um den Inhalt der Datei mithilfe einer LINQ-Abfrage abzufragen, kann die Anwendung den Inhalt der Datei in ein Array oder eine Sammlung laden. Das Laden der gesamten Datei in ein Array oder eine Sammlung verbraucht jedoch viel mehr Arbeitsspeicher als erforderlich. Die LINQ-Abfrage könnte stattdessen den Dateiinhalt mithilfe einer aufzählbaren Klasse abfragen und nur Werte zurückgeben, die den Suchkriterien entsprechen. Abfragen, die nur wenige übereinstimmende Werte zurückgeben, verbrauchen viel weniger Arbeitsspeicher.

Sie können eine Klasse erstellen, die die IEnumerable<T> Schnittstelle implementiert, um Quelldaten als aufzählbare Daten verfügbar zu machen. Ihre Klasse, die die IEnumerable(T) Schnittstelle implementiert, erfordert eine weitere Klasse, die die IEnumerator<T> Schnittstelle zum Durchlaufen der Quelldaten implementiert. Mit diesen beiden Klassen können Sie Datenelemente sequenziell als bestimmten Typ zurückgeben.

In dieser exemplarischen Vorgehensweise erstellen Sie eine Klasse, die die IEnumerable(Of String) Schnittstelle implementiert, und eine andere Klasse, die die IEnumerator(Of String) Schnittstelle implementiert, um eine Textdatei Zeile für Zeile zu lesen.

Hinweis

Auf Ihrem Computer werden möglicherweise unterschiedliche Namen oder Speicherorte für einige der Visual Studio-Benutzeroberflächenelemente in den folgenden Anweisungen angezeigt. Die Visual Studio-Edition, über die Sie verfügen, und die Einstellungen, die Sie verwenden, bestimmen diese Elemente. Weitere Informationen finden Sie unter Personalisierung der IDE.

Erstellen der enumerationsfähigen Klasse

Erstellen des aufzählbaren Klassenprojekts

  1. Zeigen Sie in Visual Basic im Menü "Datei " auf "Neu ", und klicken Sie dann auf "Projekt".

  2. Stellen Sie im Dialogfeld "Neues Projekt " im Bereich "Projekttypen " sicher, dass Windows ausgewählt ist. Wählen Sie im Bereich "Vorlagen" die Option "Klassenbibliothek" aus. Geben Sie im StreamReaderEnumerable" den Namen ein, und klicken Sie dann auf "OK". Das neue Projekt wird angezeigt.

  3. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Class1.vb Datei, und klicken Sie auf "Umbenennen". Benennen Sie die Datei in StreamReaderEnumerable.vb um und drücken Sie dann die EINGABETASTE. Beim Umbenennen der Datei wird auch die Klasse in StreamReaderEnumerable umbenannt. Diese Klasse implementiert die IEnumerable(Of String) Schnittstelle.

  4. Klicken Sie mit der rechten Maustaste auf das StreamReaderEnumerable-Projekt, zeigen Sie auf "Hinzufügen", und klicken Sie dann auf "Neues Element". Wählen Sie die Klassenvorlage aus. Geben Sie im Feld "Name"StreamReaderEnumerator.vb ein und klicken Sie auf "OK".

Die erste Klasse in diesem Projekt ist die aufzählbare Klasse und implementiert die IEnumerable(Of String) Schnittstelle. Diese generische Schnittstelle implementiert die IEnumerable-Schnittstelle und garantiert, dass Verbraucher dieser Klasse auf Werte zugreifen können, die als String typisiert sind.

Hinzufügen des Codes zum Implementieren von IEnumerable

  1. Öffnen Sie die datei StreamReaderEnumerable.vb.

  2. Geben Sie in der Zeile danach Public Class StreamReaderEnumerableFolgendes ein, und drücken Sie die EINGABETASTE.

    Implements IEnumerable(Of String)
    

    Visual Basic füllt die Klasse automatisch mit den Membern auf, die von der IEnumerable(Of String) Schnittstelle benötigt werden.

  3. Diese aufzählbare Klasse wird eine Textdatei zeilenweise, jeweils eine Zeile nach der anderen, lesen. Fügen Sie der Klasse den folgenden Code hinzu, um einen öffentlichen Konstruktor verfügbar zu machen, der einen Dateipfad als Eingabeparameter verwendet.

    Private _filePath As String
    
    Public Sub New(ByVal filePath As String)
        _filePath = filePath
    End Sub
    
  4. Ihre Implementierung der GetEnumerator-Methode der IEnumerable(Of String)-Schnittstelle gibt eine neue Instanz der StreamReaderEnumerator-Klasse zurück. Die Implementierung der GetEnumerator-Methode der IEnumerable-Schnittstelle kann Private vorgenommen werden, weil Sie nur Member der IEnumerable(Of String)-Schnittstelle verfügbar machen müssen. Ersetzen Sie den Code, den Visual Basic für die GetEnumerator Methoden generiert hat, durch den folgenden 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
    

Hinzufügen des Codes zum Implementieren von IEnumerator

  1. Öffnen Sie die StreamReaderEnumerator.vb Datei.

  2. Geben Sie in der Zeile danach Public Class StreamReaderEnumeratorFolgendes ein, und drücken Sie die EINGABETASTE.

    Implements IEnumerator(Of String)
    

    Visual Basic füllt die Klasse automatisch mit den Membern auf, die von der IEnumerator(Of String) Schnittstelle benötigt werden.

  3. Die Enumerationsklasse öffnet die Textdatei und führt die Datei-E/A aus, um die Zeilen aus der Datei zu lesen. Fügen Sie der Klasse den folgenden Code hinzu, um einen öffentlichen Konstruktor verfügbar zu machen, der einen Dateipfad als Eingabeparameter verwendet und die Textdatei zum Lesen öffnet.

    Private _sr As IO.StreamReader
    
    Public Sub New(ByVal filePath As String)
        _sr = New IO.StreamReader(filePath)
    End Sub
    
  4. Die Current Eigenschaften für die IEnumerator(Of String) und IEnumerator Schnittstellen geben das aktuelle Element aus der Textdatei als String zurück. Die Implementierung der Current-Eigenschaft der IEnumerator-Schnittstelle kann Private vorgenommen werden, weil Sie nur Member der IEnumerator(Of String)-Schnittstelle verfügbar machen müssen. Ersetzen Sie den Code, den Visual Basic für die Current Eigenschaften generiert hat, durch den folgenden 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. Die MoveNext Methode der IEnumerator Schnittstelle navigiert zum nächsten Element in der Textdatei und aktualisiert den Wert, der von der Current Eigenschaft zurückgegeben wird. Wenn keine weiteren Zu lesenden Elemente vorhanden sind, gibt die MoveNext Methode zurück False; andernfalls wird die MoveNext Methode zurückgegeben True. Fügen Sie der MoveNext -Methode den folgenden Code hinzu.

    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. Die Reset Methode der IEnumerator Schnittstelle leitet den Iterator an, auf den Anfang der Textdatei zu zeigen und den aktuellen Elementwert zu löschen. Fügen Sie der Reset -Methode den folgenden Code hinzu.

    Public Sub Reset() _
        Implements System.Collections.IEnumerator.Reset
    
        _sr.DiscardBufferedData()
        _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin)
        _current = Nothing
    End Sub
    
  7. Die Dispose Methode der IEnumerator Schnittstelle garantiert, dass alle nicht verwalteten Ressourcen freigegeben werden, bevor der Iterator zerstört wird. Das vom StreamReader Objekt verwendete Dateihandle ist eine nicht verwaltete Ressource und muss geschlossen werden, bevor die Iteratorinstanz zerstört wird. Ersetzen Sie den Code, den Visual Basic für die Dispose Methode generiert hat, durch den folgenden 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
    

Verwenden des Beispiel-Iterators

Sie können eine Enumerable-Klasse in Ihrem Code zusammen mit Kontrollstrukturen verwenden, die ein Objekt erfordern, das IEnumerable implementiert, z. B. eine For Next-Schleife oder eine LINQ-Abfrage. Das folgende Beispiel zeigt die StreamReaderEnumerable in einer LINQ-Abfrage.

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

Dim results = adminRequests.ToList()

Siehe auch