Exemplarische Vorgehensweise: Implementieren von IEnumerable(Of T) in Visual Basic
Die IEnumerable<T>-Schnittstelle wird durch Klassen implementiert, die eine Sequenz von Werten (jeweils ein Element nach dem anderen) zurückgeben können. Der Vorteil der Rückgabe einzelner Daten besteht darin, dass Sie nicht den gesamten Datensatz in den Speicher laden müssen, um mit ihm zu arbeiten. Sie müssen nur über genügend Arbeitsspeicher verfügen, um ein einziges 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 und jede Zeile aus der Datei zurückgeben muss, 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 würde jedoch viel mehr Arbeitsspeicher verbrauchen, als erforderlich ist. 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, würden viel weniger Arbeitsspeicher beanspruchen.
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 implementiert, um die Quelldaten zu durchlaufen. Diese beiden Klassen ermöglichen die sequenzielle Rückgabe von Datenelementen eines bestimmten Typs.
In dieser exemplarischen Vorgehensweise wird veranschaulicht, wie eine Klasse zum Erstellen der Schnittstelle IEnumerable(Of String)
und eine Klasse zum Erstellen der Schnittstelle IEnumerator(Of String)
erstellt wird, um eine Textdatei zeilenweise zu lesen.
Hinweis
Auf Ihrem Computer werden möglicherweise andere Namen oder Speicherorte für die Benutzeroberflächenelemente von Visual Studio angezeigt als die in den folgenden Anweisungen aufgeführten. Diese Elemente sind von der jeweiligen Visual Studio-Version und den verwendeten Einstellungen abhängig. Weitere Informationen finden Sie unter Personalisieren der IDE.
Erstellen der aufzählbaren Klasse
Erstellen des aufzählbaren Klassenprojekts
Zeigen Sie in Visual Basic im Menü Datei auf Neu, und klicken Sie dann auf Projekt.
Überprüfen Sie, ob im Dialogfeld Neues Projekt im Bereich Projekttypen der Eintrag Windows ausgewählt ist. Wählen Sie im Bereich Vorlagen die Option Klassenbibliothek aus. Geben Sie im Feld Name die Bezeichnung
StreamReaderEnumerable
ein, und klicken Sie dann auf OK. Das neue Projekt wird angezeigt.Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf die Datei „Class1.vb“, und klicken Sie auf Umbenennen. Benennen Sie die Datei in
StreamReaderEnumerable.vb
um, und drücken Sie die EINGABETASTE. Durch Umbenennen der Datei wird die Klasse ebenfalls inStreamReaderEnumerable
umbenannt. Diese Klasse implementiert dieIEnumerable(Of String)
-Schnittstelle.Klicken Sie mit der rechten Maustaste auf das Projekt StreamReaderEnumerable, zeigen Sie auf Hinzufügen, und klicken Sie dann auf Neues Element. Wählen Sie die Class-Vorlage 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. Sie implementiert die IEnumerable(Of String)
-Schnittstelle. Diese generische Schnittstelle implementiert die IEnumerable-Schnittstelle und garantiert, dass Consumer dieser Klasse auf Werte zugreifen können, die als String
typisiert sind.
Hinzufügen des Codes zum Implementieren von IEnumerable
Öffnen Sie die Datei „StreamReaderEnumerable.vb“.
Geben Sie in der Zeile nach
Public Class StreamReaderEnumerable
Folgendes ein, und drücken Sie die EINGABETASTE.Implements IEnumerable(Of String)
Visual Basic füllt die Klasse automatisch mit den Membern auf, die für die
IEnumerable(Of String)
-Schnittstelle erforderlich sind.Diese aufzählbare Klasse liest nacheinander Zeilen aus einer Textdatei. Fügen Sie der Klasse den folgenden Code hinzu, um einen öffentlichen Konstruktor verfügbar zu machen, der einen Dateipfad als Eingabeparameter annimmt.
Private _filePath As String Public Sub New(ByVal filePath As String) _filePath = filePath End Sub
Die Implementierung der GetEnumerator-Methode der
IEnumerable(Of String)
-Schnittstelle gibt eine neue Instanz derStreamReaderEnumerator
-Klasse zurück. Die Implementierung derGetEnumerator
-Methode derIEnumerable
-Schnittstelle kannPrivate
vorgenommen werden, weil Sie nur Member derIEnumerable(Of String)
-Schnittstelle verfügbar machen müssen. Ersetzen Sie den Code, den Visual Basic für dieGetEnumerator
-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
Öffnen Sie die Datei „StreamReaderEnumerator.vb“.
Geben Sie in der Zeile nach
Public Class StreamReaderEnumerator
Folgendes ein, und drücken Sie die EINGABETASTE.Implements IEnumerator(Of String)
Visual Basic füllt die Klasse automatisch mit den Membern auf, die für die
IEnumerator(Of String)
-Schnittstelle erforderlich sind.Die Enumeratorklasse ö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 annimmt, und die Textdatei zum Lesen zu öffnen.
Private _sr As IO.StreamReader Public Sub New(ByVal filePath As String) _sr = New IO.StreamReader(filePath) End Sub
Die
Current
-Eigenschaften für dieIEnumerator(Of String)
- undIEnumerator
-Schnittstellen geben das aktuelle Element aus der Textdatei alsString
zurück. Die Implementierung derCurrent
-Eigenschaft derIEnumerator
-Schnittstelle kannPrivate
vorgenommen werden, weil Sie nur Member derIEnumerator(Of String)
-Schnittstelle verfügbar machen müssen. Ersetzen Sie den Code, den Visual Basic für dieCurrent
-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
Die
MoveNext
-Methode derIEnumerator
-Schnittstelle navigiert zum nächsten Element in der Textdatei und aktualisiert den Wert, der von derCurrent
-Eigenschaft zurückgegeben wird. Wenn keine weiteren Elemente zum Lesen vorhanden sind, gibt dieMoveNext
-MethodeFalse
zurück, andernfalls gibt dieMoveNext
-MethodeTrue
zurück. Fügen Sie derMoveNext
-Methode 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
Die
Reset
-Methode derIEnumerator
-Schnittstelle weist den Iterator an, auf den Anfang der Textdatei zu zeigen, und löscht den aktuellen Elementwert. Fügen Sie derReset
-Methode folgenden Code hinzu.Public Sub Reset() _ Implements System.Collections.IEnumerator.Reset _sr.DiscardBufferedData() _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin) _current = Nothing End Sub
Die
Dispose
-Methode derIEnumerator
-Schnittstelle garantiert, dass alle nicht verwalteten Ressourcen freigegeben werden, bevor der Iterator zerstört wird. Das vomStreamReader
-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 dieDispose
-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 Beispieliterators
Sie können eine aufzählbare Klasse im Code zusammen mit Steuerungsstrukturen verwenden, die ein Objekt erfordern, das IEnumerable
implementiert, z. B. eine For Next
-Schleife oder eine LINQ-Abfrage. Das folgende Beispiel zeigt StreamReaderEnumerable
in einer LINQ-Abfrage an.
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()