Tutorial: Implementar 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 IEnumerable(T) la 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 los valores que coincidan con los criterios de búsqueda. Las consultas que devuelven solo algunos valores correspondientes consumirían mucho menos memoria.
Puede crear una clase que implemente la interfaz IEnumerable<T> para exponer los datos de origen como datos enumerables. La clase que implementa la interfaz requerirá otra clase que implemente la interfaz para IEnumerable(T) recorrer en IEnumerator<T> 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 implementa la interfaz y una clase que implementa la interfaz para leer un archivo de texto línea IEnumerable(Of String) IEnumerator(Of String) a línea.
Nota
Es posible que el equipo muestre nombres o ubicaciones diferentes para algunos de los elementos de la interfaz de usuario de Visual Studio en las siguientes instrucciones. La edición de Visual Studio que se tenga y la configuración que se utilice determinan estos elementos. Para obtener más información, vea Personalizar el IDE.
Crear la clase enumerable
Creación del proyecto de clase enumerable
En Visual Basic, en el menú Archivo , seleccione Nuevo y, a continuación, haga clic Project.
En el panel Tipos de proyecto del cuadro de diálogo Nuevo proyecto, asegúrese de que esté seleccionado Windows. Seleccione Biblioteca de clases en el panel Plantillas. En el cuadro Nombre, escriba
StreamReaderEnumerabley haga clic en Aceptar. Se muestra el nuevo proyecto.En 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.vby pulse ENTRAR. Al cambiar el nombre del archivo también se cambiará el nombre de la clase aStreamReaderEnumerable. Esta clase implementará la interfazIEnumerable(Of String).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.vby 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 interfaz y garantiza que los consumidores de esta clase puedan tener acceso a IEnumerable los valores que se escriben como String .
Agregar el código para implementar IEnumerable
Abra el archivo StreamReaderEnumerable.vb.
En la línea después
Public Class StreamReaderEnumerablede , escriba lo siguiente y presione ENTRAR.Implements IEnumerable(Of String)Visual Basic rellena automáticamente la clase con los miembros requeridos por la
IEnumerable(Of String)interfaz .Esta clase enumerable leerá líneas de un archivo de texto línea a línea. Agregue el código siguiente a la clase para exponer un constructor público que toma 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 SubLa implementación del GetEnumerator método de la interfaz devolverá una nueva instancia de la clase
IEnumerable(Of String)StreamReaderEnumerator. Se puede realizar la implementación del método de la interfaz , ya que solo tiene queGetEnumeratorexponer los miembros de laIEnumerablePrivateIEnumerable(Of String)interfaz. Reemplace el código Visual Basic generado para losGetEnumeratormé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
Agregar el código para implementar IEnumerator
Abra el archivo StreamReaderEnumerator.vb.
En la línea después
Public Class StreamReaderEnumeratorde , escriba lo siguiente y presione ENTRAR.Implements IEnumerator(Of String)Visual Basic rellena automáticamente la clase con los miembros requeridos por la
IEnumerator(Of String)interfaz .La clase de enumerador abre el archivo de texto y realiza la E/S de archivo para leer las líneas del archivo. Agregue el código siguiente a la clase para exponer un constructor público que toma una ruta de acceso de archivo como parámetro de entrada y abre 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 SubLas
Currentpropiedades de lasIEnumerator(Of String)IEnumeratorinterfaces y devuelven el elemento actual del archivo de texto comoString. Se puede realizar la implementación de la propiedad de la interfaz , ya que solo tiene queCurrentexponer los miembros de laIEnumeratorPrivateIEnumerator(Of String)interfaz. Reemplace el código Visual Basic generado para lasCurrentpropiedades 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 PropertyEl método de la interfaz navega al siguiente elemento del archivo de texto y actualiza el
MoveNextvalor devuelto por la propiedadIEnumeratorCurrent. Si no hay más elementos para leer, elMoveNextmétodo devuelve ; de loFalsecontrario, el método devuelveMoveNextTrue. Agregue el código siguiente al métodoMoveNext.Public Function MoveNext() As Boolean _ Implements System.Collections.IEnumerator.MoveNext _current = _sr.ReadLine() If _current Is Nothing Then Return False Return True End FunctionEl
Resetmétodo de la interfaz dirige al iterador para que apunte al inicio del archivo de texto y borraIEnumeratorel valor del elemento actual. Agregue el código siguiente al métodoReset.Public Sub Reset() _ Implements System.Collections.IEnumerator.Reset _sr.DiscardBufferedData() _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin) _current = Nothing End SubEl método de la interfaz garantiza que todos los recursos no administrados se liberan antes de que se destruya
DisposeIEnumeratorel iterador. El identificador de archivo que usa el objeto es un recurso no administrado y debe cerrarse antes de que se destruya la instanciaStreamReaderdel iterador. Reemplace el código Visual Basic generado para elDisposemé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 requieren un objeto que implementa , como un bucle o IEnumerable For Next una consulta LINQ. En el ejemplo siguiente se muestra StreamReaderEnumerable en una consulta LINQ.
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()