Sdílet prostřednictvím


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

  1. V jazyce Visual Basic v nabídce Soubor přejděte na příkaz Nový a klepněte na tlačítko Projekt.

  2. 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 StreamReaderEnumerablea klepněte na tlačítko OK. Zobrazí se nový projekt.

  3. 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 na StreamReaderEnumerable. Tato třída implementuje IEnumerable(Of String) rozhraní.

  4. 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

  1. Otevřete soubor StreamReaderEnumerable.vb.

  2. Na řádku za Public Class StreamReaderEnumerablezadejte 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) .

  3. 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
    
  4. Vaše implementace GetEnumerator metody IEnumerable(Of String) rozhraní vrátí novou instanci StreamReaderEnumerator třídy. Implementace GetEnumerator metody IEnumerable rozhraní může být provedena Private, protože musíte zveřejnit pouze členy IEnumerable(Of String) rozhraní. Nahraďte kód, který jazyk Visual Basic vygeneroval pro GetEnumerator 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

  1. Otevřete soubor StreamReaderEnumerator.vb.

  2. Na řádku za Public Class StreamReaderEnumeratorzadejte 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) .

  3. 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
    
  4. Vlastnosti Current obou IEnumerator(Of String)IEnumerator rozhraní vrátí aktuální položku z textového souboru jako String. Implementace Current vlastnosti IEnumerator rozhraní lze provést Private, protože musíte zveřejnit pouze členy IEnumerator(Of String) rozhraní. Nahraďte kód, který jazyk Visual Basic vygeneroval pro Current 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
    
  5. MoveNext Metoda IEnumerator rozhraní přejde na další položku v textovém souboru a aktualizuje hodnotu vrácenou Current vlastností. Pokud nejsou k dispozici žádné další položky ke čtení, MoveNext metoda vrátí False; jinak MoveNext metoda vrátí True. Do metody MoveNext 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
    
  6. Reset Metoda IEnumerator rozhraní směruje iterátor na začátek textového souboru a vymaže hodnotu aktuální položky. Do metody Reset 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
    
  7. Metoda DisposeIEnumerator rozhraní zaručuje, že všechny nespravované prostředky jsou vydány před zničením iterátoru. Popisovač souboru používaný objektem StreamReader 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 metodu Dispose 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()

Viz také