Compartir a través de


Tutorial: Implementación de IEnumerable(Of T) en Visual Basic

La IEnumerable<T> interfaz se implementa mediante clases que pueden devolver una secuencia de valores de un elemento a la vez. La ventaja de devolver datos de un elemento a la vez es que no es necesario cargar el conjunto completo de datos en la memoria para trabajar con él. Solo tiene que usar memoria suficiente para cargar un solo elemento de los datos. Las clases que implementan la IEnumerable(T) interfaz se pueden usar con For Each bucles o consultas LINQ.

Por ejemplo, considere una aplicación que debe leer un archivo de texto grande y devolver cada línea del archivo que coincida con determinados criterios de búsqueda. La aplicación usa una consulta LINQ para devolver líneas del archivo que coinciden con los criterios especificados. Para consultar el contenido del archivo mediante una consulta LINQ, la aplicación podría cargar el contenido del archivo en una matriz o una colección. Sin embargo, cargar todo el archivo en una matriz o colección consumiría mucho más memoria de la necesaria. En su lugar, la consulta LINQ podría consultar el contenido del archivo mediante una clase enumerable y devolver solo valores que coincidan con los criterios de búsqueda. Las consultas que devuelven solo unos pocos valores coincidentes consumirían mucha menos memoria.

Puede crear una clase que implemente la IEnumerable<T> interfaz para exponer los datos de origen como datos enumerables. La clase que implementa la IEnumerable(T) interfaz requerirá otra clase que implemente la IEnumerator<T> interfaz para recorrer en iteración los datos de origen. Estas dos clases permiten devolver elementos de datos secuencialmente como un tipo específico.

En este tutorial, creará una clase que implemente la IEnumerable(Of String) interfaz y una clase que implemente la IEnumerator(Of String) interfaz para leer un archivo de texto una línea a la vez.

Nota:

El equipo puede mostrar nombres o ubicaciones diferentes para algunos de los elementos de la interfaz de usuario de Visual Studio en las instrucciones siguientes. La edición de Visual Studio que tiene y la configuración que usa determinan estos elementos. Para obtener más información, consulte Personalizando el IDE.

Crear la clase enumerable

Creación del proyecto de clase enumerable

  1. En Visual Basic, en el menú Archivo , seleccione Nuevo y, a continuación, haga clic en Proyecto.

  2. En el cuadro de diálogo Nuevo proyecto , en el panel Tipos de proyecto , asegúrese de que Windows está seleccionado. Seleccione Biblioteca de Clases en el panel de Plantillas. En el cuadro Nombre , escriba StreamReaderEnumerabley, a continuación, haga clic en Aceptar. Se muestra el nuevo proyecto.

  3. En el Explorador de soluciones, haga clic con el botón derecho en el archivo Class1.vb y haga clic en Cambiar nombre. Cambie el nombre del archivo a StreamReaderEnumerable.vb y presione ENTRAR. Cambiar el nombre del archivo también cambiará el nombre de la clase a StreamReaderEnumerable. Esta clase implementará la IEnumerable(Of String) interfaz .

  4. Haga clic con el botón derecho en el proyecto StreamReaderEnumerable, seleccione Agregar y, a continuación, haga clic en Nuevo elemento. Seleccione la plantilla Clase . En el cuadro Nombre , escriba StreamReaderEnumerator.vb y haga clic en Aceptar.

La primera clase de este proyecto es la clase enumerable e implementará la IEnumerable(Of String) interfaz . Esta interfaz genérica implementa la IEnumerable interfaz y garantiza que los consumidores de esta clase puedan acceder a los valores tipados como String.

Adición del código para implementar IEnumerable

  1. Abra el archivo StreamReaderEnumerable.vb.

  2. En la línea después de Public Class StreamReaderEnumerable, escriba lo siguiente y presione Enter.

    Implements IEnumerable(Of String)
    

    Visual Basic rellena automáticamente la clase con los miembros necesarios para la IEnumerable(Of String) interfaz.

  3. Esta clase enumerable leerá líneas de un archivo de texto una línea a la vez. Agregue el código siguiente a la clase para exponer un constructor público que tome una ruta de acceso de archivo como parámetro de entrada.

    Private _filePath As String
    
    Public Sub New(ByVal filePath As String)
        _filePath = filePath
    End Sub
    
  4. La implementación del GetEnumerator método de la IEnumerable(Of String) interfaz devolverá una nueva instancia de la StreamReaderEnumerator clase . La implementación del método GetEnumerator de la interfaz IEnumerable se puede establecer como Private porque solamente hay que exponer miembros de la interfaz IEnumerable(Of String). Reemplace el código que Visual Basic generó para los GetEnumerator métodos por el código siguiente.

    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
    

Adición del código para implementar IEnumerator

  1. Abra el archivo StreamReaderEnumerator.vb.

  2. En la línea después de Public Class StreamReaderEnumerator, escriba lo siguiente y presione Enter.

    Implements IEnumerator(Of String)
    

    Visual Basic rellena automáticamente la clase con los miembros necesarios para la IEnumerator(Of String) interfaz.

  3. La clase enumeradora abre el archivo de texto y realiza operaciones de entrada/salida para leer las líneas de texto. Agregue el código siguiente a la clase para exponer un constructor público que tome una ruta de acceso de archivo como parámetro de entrada y abra el archivo de texto para su lectura.

    Private _sr As IO.StreamReader
    
    Public Sub New(ByVal filePath As String)
        _sr = New IO.StreamReader(filePath)
    End Sub
    
  4. Las propiedades Current de ambas interfaces IEnumerator(Of String) y IEnumerator devuelven el elemento actual del archivo de texto como un String. La implementación de la propiedad Current de la interfaz IEnumerator se puede establecer como Private porque solamente hay que exponer miembros de la interfaz IEnumerator(Of String). Reemplace el código que Visual Basic generó para las Current propiedades por el código siguiente.

    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. El MoveNext método de la IEnumerator interfaz navega al siguiente elemento del archivo de texto y actualiza el valor devuelto por la Current propiedad . Si no hay más elementos que leer, el MoveNext método devuelve False; de lo contrario, el MoveNext método devuelve True. Agregue el siguiente código al método MoveNext.

    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. El método Reset de la interfaz IEnumerator dirige al iterador para que apunte al inicio del archivo de texto y borra el valor del elemento actual. Agregue el siguiente código al método Reset.

    Public Sub Reset() _
        Implements System.Collections.IEnumerator.Reset
    
        _sr.DiscardBufferedData()
        _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin)
        _current = Nothing
    End Sub
    
  7. El Dispose método de la IEnumerator interfaz garantiza que todos los recursos no administrados se liberen antes de que se destruya el iterador. El identificador de archivo que usa el StreamReader objeto es un recurso no administrado y debe cerrarse antes de que se destruya la instancia del iterador. Reemplace el código que Visual Basic generó para el Dispose método por el código siguiente.

    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 del iterador de ejemplo

Puede usar una clase enumerable en el código junto con estructuras de control que requieran un objeto que implemente IEnumerable, como un For Next bucle o una consulta LINQ. El siguiente ejemplo muestra el StreamReaderEnumerable en una consulta LINQ.

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

Dim results = adminRequests.ToList()

Consulte también