Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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
Zeigen Sie in Visual Basic im Menü "Datei " auf "Neu ", und klicken Sie dann auf "Projekt".
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.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.vbum und drücken Sie dann die EINGABETASTE. Beim Umbenennen der Datei wird auch die Klasse inStreamReaderEnumerableumbenannt. Diese Klasse implementiert dieIEnumerable(Of String)Schnittstelle.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.vbein 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
Öffnen Sie die datei StreamReaderEnumerable.vb.
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.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 SubIhre Implementierung der GetEnumerator-Methode der
IEnumerable(Of String)-Schnittstelle gibt eine neue Instanz derStreamReaderEnumerator-Klasse zurück. Die Implementierung derGetEnumerator-Methode derIEnumerable-Schnittstelle kannPrivatevorgenommen werden, weil Sie nur Member derIEnumerable(Of String)-Schnittstelle verfügbar machen müssen. Ersetzen Sie den Code, den Visual Basic für dieGetEnumeratorMethoden 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 StreamReaderEnumerator.vb Datei.
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.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 SubDie
CurrentEigenschaften für dieIEnumerator(Of String)undIEnumeratorSchnittstellen geben das aktuelle Element aus der Textdatei alsStringzurück. Die Implementierung derCurrent-Eigenschaft derIEnumerator-Schnittstelle kannPrivatevorgenommen werden, weil Sie nur Member derIEnumerator(Of String)-Schnittstelle verfügbar machen müssen. Ersetzen Sie den Code, den Visual Basic für dieCurrentEigenschaften 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 PropertyDie
MoveNextMethode derIEnumeratorSchnittstelle navigiert zum nächsten Element in der Textdatei und aktualisiert den Wert, der von derCurrentEigenschaft zurückgegeben wird. Wenn keine weiteren Zu lesenden Elemente vorhanden sind, gibt dieMoveNextMethode zurückFalse; andernfalls wird dieMoveNextMethode zurückgegebenTrue. Fügen Sie derMoveNext-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 FunctionDie
ResetMethode derIEnumeratorSchnittstelle leitet den Iterator an, auf den Anfang der Textdatei zu zeigen und den aktuellen Elementwert zu löschen. Fügen Sie derReset-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 SubDie
DisposeMethode derIEnumeratorSchnittstelle garantiert, dass alle nicht verwalteten Ressourcen freigegeben werden, bevor der Iterator zerstört wird. Das vomStreamReaderObjekt 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 dieDisposeMethode 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()