Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
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
Wijs in Visual Basic in het menu Bestand de optie Nieuw aan en klik vervolgens op Project.
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
StreamReaderEnumerablein het vak Naam. Het nieuwe project wordt weergegeven.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.vben druk op Enter. Als u de naam van het bestand wijzigt, wordt ook de naam van de klasse gewijzigd inStreamReaderEnumerable. Met deze klasse wordt deIEnumerable(Of String)interface geïmplementeerd.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.vbin 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
Open het bestand StreamReaderEnumerable.vb.
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.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 SubUw implementatie van de GetEnumerator methode van de
IEnumerable(Of String)interface retourneert een nieuw exemplaar van deStreamReaderEnumeratorklasse. De implementatie van deGetEnumerator-methode van deIEnumerable-interface kanPrivateworden gemaakt, omdat u alleen de leden van deIEnumerable(Of String)-interface beschikbaar hoeft te stellen. Vervang de code die Visual Basic voor deGetEnumeratormethoden 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
Open het StreamReaderEnumerator.vb-bestand.
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.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 SubDe
Currenteigenschappen voor zowel deIEnumerator(Of String)alsIEnumeratorinterfaces retourneren het huidige item uit het tekstbestand als eenString. De implementatie van deCurrenteigenschap van deIEnumeratorinterface kanPrivateworden uitgevoerd, omdat u alleen leden van deIEnumerator(Of String)interface moet onthullen. Vervang de code die Visual Basic voor deCurrenteigenschappen 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 PropertyDe
MoveNextmethode van deIEnumeratorinterface gaat naar het volgende item in het tekstbestand en werkt de waarde bij die door deCurrenteigenschap wordt geretourneerd. Als er geen items meer te lezen zijn, retourneert deMoveNext-methodeFalse; anders retourneert deMoveNext-methodeTrue. Voeg de volgende code toe aan de methodeMoveNext.Public Function MoveNext() As Boolean _ Implements System.Collections.IEnumerator.MoveNext _current = _sr.ReadLine() If _current Is Nothing Then Return False Return True End FunctionMet
Resetde methode van deIEnumeratorinterface wordt de iterator doorgestuurd naar het begin van het tekstbestand en wordt de huidige itemwaarde gewist. Voeg de volgende code toe aan de methodeReset.Public Sub Reset() _ Implements System.Collections.IEnumerator.Reset _sr.DiscardBufferedData() _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin) _current = Nothing End SubDe
Disposemethode van deIEnumeratorinterface garandeert dat alle niet-beheerde resources worden vrijgegeven voordat de iterator wordt vernietigd. De bestandsgreep die door hetStreamReaderobject wordt gebruikt, is een niet-beheerde resource en moet worden gesloten voordat het iterator-exemplaar wordt vernietigd. Vervang de code die Visual Basic voor deDisposemethode 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()