Procedura dettagliata: Implementazione IEnumerable(Of T) in Visual BasicWalkthrough: Implementing IEnumerable(Of T) in Visual Basic

Il IEnumerable<T> interfaccia è implementata da classi che possono restituire una sequenza di valori di un elemento alla volta.The IEnumerable<T> interface is implemented by classes that can return a sequence of values one item at a time. Il vantaggio di restituzione di dati è un elemento in un momento non è necessario caricare il set completo di dati in memoria sul relativo utilizzo.The advantage of returning data one item at a time is that you do not have to load the complete set of data into memory to work with it. È sufficiente usare quantità di memoria sufficiente per caricare un singolo elemento dai dati.You only have to use sufficient memory to load a single item from the data. Le classi che implementano il IEnumerable(T) interfaccia può essere usata con For Each cicli o query LINQ.Classes that implement the IEnumerable(T) interface can be used with For Each loops or LINQ queries.

Ad esempio, si consideri un'applicazione che deve leggere un file di testo di grandi dimensioni e restituire ogni riga del file che corrisponde ai criteri di ricerca specifico.For example, consider an application that must read a large text file and return each line from the file that matches particular search criteria. L'applicazione usa una query LINQ per restituire le righe dal file che corrispondono ai criteri specificati.The application uses a LINQ query to return lines from the file that match the specified criteria. Per eseguire query sul contenuto del file usando una query LINQ, l'applicazione è stato possibile caricare il contenuto del file in una matrice o una raccolta.To query the contents of the file by using a LINQ query, the application could load the contents of the file into an array or a collection. Tuttavia, il caricamento dell'intero file in una matrice o raccolta richiederebbe più memoria rispetto a quelli necessari.However, loading the whole file into an array or collection would consume far more memory than is required. La query LINQ può invece eseguire una query il contenuto del file usando una classe enumerable, che restituisce solo i valori che corrispondono ai criteri di ricerca.The LINQ query could instead query the file contents by using an enumerable class, returning only values that match the search criteria. Le query che restituiscono solo alcuni valori corrispondenti richiederebbe molto meno memoria.Queries that return only a few matching values would consume far less memory.

È possibile creare una classe che implementa il IEnumerable<T> interfaccia da esporre dati di origine dati enumerabili.You can create a class that implements the IEnumerable<T> interface to expose source data as enumerable data. Classe che implementa il IEnumerable(T) interfaccia richiederà un'altra classe che implementa il IEnumerator<T> interfaccia per scorrere i dati di origine.Your class that implements the IEnumerable(T) interface will require another class that implements the IEnumerator<T> interface to iterate through the source data. Queste due classi consentono di restituire gli elementi di dati in sequenza come un tipo specifico.These two classes enable you to return items of data sequentially as a specific type.

In questa procedura dettagliata, si creerà una classe che implementa il IEnumerable(Of String) interfaccia e una classe che implementa il IEnumerator(Of String) interfaccia per leggere un file di testo una riga alla volta.In this walkthrough, you will create a class that implements the IEnumerable(Of String) interface and a class that implements the IEnumerator(Of String) interface to read a text file one line at a time.

Nota

Nomi o percorsi visualizzati per alcuni elementi dell'interfaccia utente di Visual Studio nelle istruzioni seguenti potrebbero essere diversi nel computer in uso.Your computer might show different names or locations for some of the Visual Studio user interface elements in the following instructions. La versione di Visual Studio in uso e le impostazioni configurate determinano questi elementi.The Visual Studio edition that you have and the settings that you use determine these elements. Per altre informazioni, vedere Personalizzazione dell'IDE.For more information, see Personalizing the IDE.

Creazione della classe EnumerableCreating the Enumerable Class

Creare il progetto della classe enumerableCreate the enumerable class project

  1. In Visual Basic nel File dal menu New e quindi fare clic su progetto.In Visual Basic, on the File menu, point to New and then click Project.

  2. Nel riquadro Tipi di progetto della finestra di dialogo Nuovo progetto verificare che sia selezionata l'opzione Windows.In the New Project dialog box, in the Project Types pane, make sure that Windows is selected. Selezionare Libreria di classi nel riquadro Modelli.Select Class Library in the Templates pane. Nella casella Nome digitare StreamReaderEnumerable e quindi fare clic su OK.In the Name box, type StreamReaderEnumerable, and then click OK. Viene visualizzato il nuovo progetto.The new project is displayed.

  3. Nelle Esplora soluzioni, fare doppio clic su file Class1.vb e fare clic su rinominare.In Solution Explorer, right-click the Class1.vb file and click Rename. Rinominare il file StreamReaderEnumerable.vb e premere INVIO.Rename the file to StreamReaderEnumerable.vb and press ENTER. Modificando il nome del file, anche la classe verrà rinominata StreamReaderEnumerable.Renaming the file will also rename the class to StreamReaderEnumerable. Questa classe implementerà l'interfaccia IEnumerable(Of String).This class will implement the IEnumerable(Of String) interface.

  4. Pulsante destro del mouse sul progetto StreamReaderEnumerable, scegliere Add, quindi fare clic su nuovo elemento.Right-click the StreamReaderEnumerable project, point to Add, and then click New Item. Selezionare il classe modello.Select the Class template. Nel Name , digitare StreamReaderEnumerator.vb e fare clic su OK.In the Name box, type StreamReaderEnumerator.vb and click OK.

La prima classe nel progetto è la classe enumerable e verrà implementata il IEnumerable(Of String) interfaccia.The first class in this project is the enumerable class and will implement the IEnumerable(Of String) interface. Questa interfaccia generica implementa il IEnumerable interfaccia e fa in modo che i consumer di questa classe possono accedere a valori tipizzati come String.This generic interface implements the IEnumerable interface and guarantees that consumers of this class can access values typed as String.

Aggiungere il codice per implementare IEnumerableAdd the code to implement IEnumerable

  1. Aprire il file StreamReaderEnumerable.Open the StreamReaderEnumerable.vb file.

  2. Nella riga successiva Public Class StreamReaderEnumerable, digitare il comando seguente e premere INVIO.On the line after Public Class StreamReaderEnumerable, type the following and press ENTER.

    Implements IEnumerable(Of String)
    

    Visual Basic popola automaticamente la classe con i membri necessari per il IEnumerable(Of String) interfaccia.Visual Basic automatically populates the class with the members that are required by the IEnumerable(Of String) interface.

  3. Questa classe enumerable leggerà le righe da un file di testo una riga alla volta.This enumerable class will read lines from a text file one line at a time. Aggiungere il codice seguente alla classe per esporre un costruttore pubblico che accetta un percorso di file come parametro di input.Add the following code to the class to expose a public constructor that takes a file path as an input parameter.

    Private _filePath As String
    
    Public Sub New(ByVal filePath As String)
        _filePath = filePath
    End Sub
    
  4. L'implementazione del GetEnumerator metodo per il IEnumerable(Of String) interfaccia restituirà una nuova istanza del StreamReaderEnumerator classe.Your implementation of the GetEnumerator method of the IEnumerable(Of String) interface will return a new instance of the StreamReaderEnumerator class. L'implementazione del GetEnumerator metodo per il IEnumerable interfaccia può essere reso Private, in quanto è necessario esporre solo i membri del IEnumerable(Of String) interfaccia.The implementation of the GetEnumerator method of the IEnumerable interface can be made Private, because you have to expose only members of the IEnumerable(Of String) interface. Sostituire il codice Visual Basic generato per il GetEnumerator metodi con il codice seguente.Replace the code that Visual Basic generated for the GetEnumerator methods with the following 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
    

Aggiungere il codice per l'implementazione di IEnumeratorAdd the code to implement IEnumerator

  1. Aprire il file StreamReaderEnumerator.Open the StreamReaderEnumerator.vb file.

  2. Nella riga successiva Public Class StreamReaderEnumerator, digitare il comando seguente e premere INVIO.On the line after Public Class StreamReaderEnumerator, type the following and press ENTER.

    Implements IEnumerator(Of String)
    

    Visual Basic popola automaticamente la classe con i membri necessari per il IEnumerator(Of String) interfaccia.Visual Basic automatically populates the class with the members that are required by the IEnumerator(Of String) interface.

  3. La classe dell'enumeratore consente di aprire il file di testo ed esegue il file dei / o per leggere le righe dal file.The enumerator class opens the text file and performs the file I/O to read the lines from the file. Aggiungere il codice seguente alla classe per esporre un costruttore pubblico che accetta un percorso di file come parametro di input e aprire il file di testo per la lettura.Add the following code to the class to expose a public constructor that takes a file path as an input parameter and open the text file for reading.

    Private _sr As IO.StreamReader
    
    Public Sub New(ByVal filePath As String)
        _sr = New IO.StreamReader(filePath)
    End Sub
    
  4. Il Current delle proprietà per entrambi i IEnumerator(Of String) e IEnumerator interfacce restituiscono l'elemento corrente dal file di testo come un String.The Current properties for both the IEnumerator(Of String) and IEnumerator interfaces return the current item from the text file as a String. L'implementazione del Current proprietà del IEnumerator interfaccia può essere reso Private, in quanto è necessario esporre solo i membri del IEnumerator(Of String) interfaccia.The implementation of the Current property of the IEnumerator interface can be made Private, because you have to expose only members of the IEnumerator(Of String) interface. Sostituire il codice Visual Basic generato per il Current proprietà con il codice seguente.Replace the code that Visual Basic generated for the Current properties with the following 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
    
  5. Il MoveNext metodo per il IEnumerator interfaccia passa all'elemento successivo nel file di testo e aggiorna il valore restituito dal Current proprietà.The MoveNext method of the IEnumerator interface navigates to the next item in the text file and updates the value that is returned by the Current property. Se non esistono nessun ulteriore elemento da leggere, il MoveNext restituzione del metodo False; in caso contrario, il MoveNext restituzione del metodo True.If there are no more items to read, the MoveNext method returns False; otherwise the MoveNext method returns True. Aggiungere al metodo MoveNext il seguente codice.Add the following code to the MoveNext method.

    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. Il Reset metodo di IEnumerator interfaccia indirizza l'iteratore in modo che punti all'inizio del file di testo e cancella il valore dell'elemento corrente.The Reset method of the IEnumerator interface directs the iterator to point to the start of the text file and clears the current item value. Aggiungere al metodo Reset il seguente codice.Add the following code to the Reset method.

    Public Sub Reset() _
        Implements System.Collections.IEnumerator.Reset
    
        _sr.DiscardBufferedData()
        _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin)
        _current = Nothing
    End Sub
    
  7. Il Dispose metodo di IEnumerator interfaccia garantisce che tutte le risorse non gestite vengono rilasciate prima dell'eliminazione permanente dell'iteratore.The Dispose method of the IEnumerator interface guarantees that all unmanaged resources are released before the iterator is destroyed. L'handle di file che viene usato per il StreamReader oggetto è una risorsa non gestita e deve essere chiuso prima che l'istanza dell'iteratore viene eliminato definitivamente.The file handle that is used by the StreamReader object is an unmanaged resource and must be closed before the iterator instance is destroyed. Sostituire il codice Visual Basic generato per il Dispose metodo con il codice seguente.Replace the code that Visual Basic generated for the Dispose method with the following 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
    

Usando l'iteratore di esempioUsing the Sample Iterator

È possibile usare una classe enumerable nel codice insieme alle strutture di controllo che richiedono un oggetto che implementa IEnumerable, ad esempio un For Next ciclo o una query LINQ.You can use an enumerable class in your code together with control structures that require an object that implements IEnumerable, such as a For Next loop or a LINQ query. L'esempio seguente illustra il StreamReaderEnumerable in una query LINQ.The following example shows the StreamReaderEnumerable in a LINQ query.

Dim adminRequests = 
    From line In New StreamReaderEnumerable("..\..\log.txt")
    Where line.Contains("admin.aspx 401")

Dim results = adminRequests.ToList()

Vedere ancheSee also