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

L' IEnumerable<T> interfaccia viene implementata da classi che possono restituire una sequenza di valori 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 restituire dati un elemento alla volta è che non è necessario caricare il set completo di dati in memoria per utilizzarlo.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 utilizzare 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 l' IEnumerable(T) interfaccia possono essere utilizzate con i For Each cicli o le query LINQ.Classes that implement the IEnumerable(T) interface can be used with For Each loops or LINQ queries.

Si consideri, ad esempio, un'applicazione che deve leggere un file di testo di grandi dimensioni e restituire ogni riga del file che corrisponde a criteri di ricerca specifici.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 del 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 una query sul contenuto del file utilizzando una query LINQ, l'applicazione potrebbe caricare il contenuto del file in una matrice o in 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 in una raccolta utilizzerebbe una quantità di memoria maggiore di quella richiesta.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 sul contenuto del file usando una classe Enumerable, restituendo 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 pochi valori corrispondenti utilizzeranno una quantità di memoria molto inferiore.Queries that return only a few matching values would consume far less memory.

È possibile creare una classe che implementi l' IEnumerable<T> interfaccia per esporre i dati di origine come dati enumerabili.You can create a class that implements the IEnumerable<T> interface to expose source data as enumerable data. La classe che implementa l' IEnumerable(T) interfaccia richiede un'altra classe che implementa l' IEnumerator<T> interfaccia per eseguire l'iterazione dei 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 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 verrà creata una classe che implementa l' IEnumerable(Of String) interfaccia e una classe che implementa l' 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 di classe EnumerableCreate the enumerable class project

  1. In Visual Basic scegliere nuovo dal menu file , 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, quindi fare clic su OK.In the Name box, type StreamReaderEnumerable, and then click OK. Verrà visualizzato il nuovo progetto.The new project is displayed.

  3. In Esplora soluzioni fare clic con il pulsante destro del mouse sul file Class1. vb e scegliere Rinomina.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. Fare clic con il pulsante destro del mouse sul progetto StreamReaderEnumerable, scegliere Aggiungi, quindi fare clic su nuovo elemento.Right-click the StreamReaderEnumerable project, point to Add, and then click New Item. Selezionare il modello di classe .Select the Class template. Digitare StreamReaderEnumerator.vb nella casella Nome e quindi fare clic su OK.In the Name box, type StreamReaderEnumerator.vb and click OK.

La prima classe in questo progetto è la classe Enumerable e implementa l' 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 l' IEnumerable interfaccia e garantisce che gli utenti di questa classe possano accedere ai 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. vb.Open the StreamReaderEnumerable.vb file.

  2. Nella riga dopo 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 richiesti dall' 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 enumerabile 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 dell' IEnumerable(Of String) interfaccia restituirà una nuova istanza della 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 dell' IEnumerable interfaccia può essere eseguita Private , perché è necessario esporre solo i membri dell' 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 generato Visual Basic per i 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 implementare IEnumeratorAdd the code to implement IEnumerator

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

  2. Nella riga dopo 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 richiesti dall' 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 Enumerator apre il file di testo ed esegue l'I/O del file 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. Le Current proprietà per entrambe le IEnumerator(Of String) IEnumerator interfacce e restituiscono l'elemento corrente dal file di testo come 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 della Current proprietà dell' IEnumerator interfaccia può essere eseguita Private , perché è necessario esporre solo i membri dell' 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 generato Visual Basic per le 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 dell' IEnumerator interfaccia passa all'elemento successivo nel file di testo e aggiorna il valore restituito dalla 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 sono presenti altri elementi da leggere, il MoveNext metodo restituisce False ; in caso contrario, il MoveNext metodo restituisce True .If there are no more items to read, the MoveNext method returns False; otherwise the MoveNext method returns True. Aggiungere il codice seguente al metodo MoveNext .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 dell' 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 il codice seguente al metodo Reset .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 dell' IEnumerator interfaccia garantisce che tutte le risorse non gestite vengano rilasciate prima che l'iteratore venga eliminato definitivamente.The Dispose method of the IEnumerator interface guarantees that all unmanaged resources are released before the iterator is destroyed. L'handle di file usato dall' StreamReader oggetto è una risorsa non gestita e deve essere chiuso prima che venga distrutta l'istanza dell'iteratore.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 generato Visual Basic 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
    

Uso dell'iteratore di esempioUsing the Sample Iterator

È possibile usare una classe Enumerable nel codice insieme a 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. Nell'esempio seguente viene illustrato l'oggetto 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()

Vedi ancheSee also