Návod: Implementace IEnumerable(Of T) v jazyce Visual Basic
Rozhraní IEnumerable<T> je implementováno třídami, které mohou vrátit posloupnost hodnot jedné položky najednou. Výhodou vrácení dat o jednu položku najednou je, že nemusíte načítat úplnou sadu dat do paměti, aby s ní mohli pracovat. K načtení jedné položky z dat stačí dostatek paměti. Třídy, které implementují IEnumerable(T)
rozhraní, lze použít se For Each
smyčkami nebo dotazy LINQ.
Představte si například aplikaci, která musí číst velký textový soubor a vracet každý řádek ze souboru, který odpovídá konkrétním kritériím hledání. Aplikace používá dotaz LINQ k vrácení řádků ze souboru, které odpovídají zadaným kritériím. Pokud chcete dotazovat obsah souboru pomocí dotazu LINQ, může aplikace načíst obsah souboru do pole nebo kolekce. Načtení celého souboru do pole nebo kolekce by však spotřebovalo mnohem více paměti, než je potřeba. Dotaz LINQ by mohl místo toho dotazovat obsah souboru pomocí výčtové třídy, která vrací pouze hodnoty, které odpovídají kritériím hledání. Dotazy, které vracejí pouze několik odpovídajících hodnot, spotřebovávají mnohem méně paměti.
Můžete vytvořit třídu, která implementuje IEnumerable<T> rozhraní pro zveřejnění zdrojových dat jako výčtových dat. Vaše třída, která implementuje IEnumerable(T)
rozhraní, bude vyžadovat další třídu, která implementuje IEnumerator<T> rozhraní pro iteraci prostřednictvím zdrojových dat. Tyto dvě třídy umožňují vracet položky dat postupně jako konkrétní typ.
V tomto názorném postupu vytvoříte třídu, která implementuje IEnumerable(Of String)
rozhraní a třídu, která implementuje IEnumerator(Of String)
rozhraní pro čtení textového souboru po jednom řádku.
Poznámka:
Váš počítač může v následujících pokynech zobrazovat odlišné názvy nebo umístění některých prvků uživatelského rozhraní sady Visual Studio. Tyto prvky jsou určeny edicí sady Visual Studio a použitým nastavením. Další informace najdete v tématu Přizpůsobení integrovaného vývojového prostředí.
Vytvoření výčtové třídy
Vytvoření projektu výčtu tříd
V jazyce Visual Basic v nabídce Soubor přejděte na příkaz Nový a klepněte na tlačítko Projekt.
V dialogovém okně Nový projekt v podokně Typy projektů se ujistěte, že je vybraná možnost Windows . V podokně Šablony vyberte knihovnutříd. Do pole Název zadejte
StreamReaderEnumerable
a klepněte na tlačítko OK. Zobrazí se nový projekt.V Průzkumník řešení klikněte pravým tlačítkem myši na soubor Class1.vb a klikněte na Přejmenovat. Přejmenujte soubor na
StreamReaderEnumerable.vb
a stiskněte ENTER. Přejmenování souboru také přejmenuje třídu naStreamReaderEnumerable
. Tato třída implementujeIEnumerable(Of String)
rozhraní.Klikněte pravým tlačítkem myši na projekt StreamReaderEnumerable, přejděte na příkaz Přidat a klepněte na tlačítko Nová položka. Vyberte šablonu třídy. Do pole Název zadejte
StreamReaderEnumerator.vb
a klepněte na tlačítko OK.
První třída v tomto projektu je výčtová třída a implementuje IEnumerable(Of String)
rozhraní. Toto obecné rozhraní implementuje IEnumerable rozhraní a zaručuje, že uživatelé této třídy mohou přistupovat k hodnotám zadaným jako String
.
Přidání kódu pro implementaci IEnumerable
Otevřete soubor StreamReaderEnumerable.vb.
Na řádku za
Public Class StreamReaderEnumerable
zadejte následující a stiskněte enter.Implements IEnumerable(Of String)
Visual Basic automaticky naplní třídu členy, které jsou požadovány rozhraním
IEnumerable(Of String)
.Tato výčtová třída bude číst řádky z textového souboru po jednom řádku. Do třídy přidejte následující kód, který zveřejní veřejný konstruktor, který jako vstupní parametr vezme cestu k souboru.
Private _filePath As String Public Sub New(ByVal filePath As String) _filePath = filePath End Sub
Vaše implementace GetEnumerator metody
IEnumerable(Of String)
rozhraní vrátí novou instanciStreamReaderEnumerator
třídy. ImplementaceGetEnumerator
metodyIEnumerable
rozhraní může být provedenaPrivate
, protože musíte zveřejnit pouze členyIEnumerable(Of String)
rozhraní. Nahraďte kód, který jazyk Visual Basic vygeneroval proGetEnumerator
metody následujícím kódem.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
Přidání kódu pro implementaci IEnumeratoru
Otevřete soubor StreamReaderEnumerator.vb.
Na řádku za
Public Class StreamReaderEnumerator
zadejte následující a stiskněte enter.Implements IEnumerator(Of String)
Visual Basic automaticky naplní třídu členy, které jsou požadovány rozhraním
IEnumerator(Of String)
.Třída enumerátoru otevře textový soubor a provede vstupně-výstupní operace souboru pro čtení řádků ze souboru. Do třídy přidejte následující kód, který zpřístupní veřejný konstruktor, který vezme cestu k souboru jako vstupní parametr a otevře textový soubor pro čtení.
Private _sr As IO.StreamReader Public Sub New(ByVal filePath As String) _sr = New IO.StreamReader(filePath) End Sub
Vlastnosti
Current
obouIEnumerator(Of String)
IEnumerator
rozhraní vrátí aktuální položku z textového souboru jakoString
. ImplementaceCurrent
vlastnostiIEnumerator
rozhraní lze provéstPrivate
, protože musíte zveřejnit pouze členyIEnumerator(Of String)
rozhraní. Nahraďte kód, který jazyk Visual Basic vygeneroval proCurrent
vlastnosti, následujícím kódem.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
MoveNext
MetodaIEnumerator
rozhraní přejde na další položku v textovém souboru a aktualizuje hodnotu vrácenouCurrent
vlastností. Pokud nejsou k dispozici žádné další položky ke čtení,MoveNext
metoda vrátíFalse
; jinakMoveNext
metoda vrátíTrue
. Do metodyMoveNext
přidejte následující kód.Public Function MoveNext() As Boolean _ Implements System.Collections.IEnumerator.MoveNext _current = _sr.ReadLine() If _current Is Nothing Then Return False Return True End Function
Reset
MetodaIEnumerator
rozhraní směruje iterátor na začátek textového souboru a vymaže hodnotu aktuální položky. Do metodyReset
přidejte následující kód.Public Sub Reset() _ Implements System.Collections.IEnumerator.Reset _sr.DiscardBufferedData() _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin) _current = Nothing End Sub
Metoda
Dispose
IEnumerator
rozhraní zaručuje, že všechny nespravované prostředky jsou vydány před zničením iterátoru. Popisovač souboru používaný objektemStreamReader
je nespravovaný prostředek a musí být uzavřen před zničením instance iterátoru. Nahraďte kód, který jazyk Visual Basic vygeneroval pro metoduDispose
následujícím kódem.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
Použití ukázkového iterátoru
V kódu můžete použít výčtovou třídu společně s řídicími strukturami, které vyžadují objekt, který implementuje IEnumerable
, například For Next
smyčku nebo dotaz LINQ. Následující příklad ukazuje StreamReaderEnumerable
v dotazu LINQ.
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()