Tutorial: Implementar IEnumerable(Of T) en Visual Basic
Artículo
La interfaz IEnumerable<T> se implementa mediante clases que pueden devolver una secuencia de valores uno a uno. La ventaja de devolver los datos uno a uno es que no es necesario cargar todo el conjunto de datos en la memoria para poder trabajar con él. Solo tiene que usar la memoria suficiente para cargar un solo elemento de los datos. Las clases que implementan la interfaz IEnumerable(T) se pueden usar con bucles For Each o consultas LINQ.
Por ejemplo, considere una aplicación que debe leer un archivo de texto grande y devolver cada una de las líneas del archivo que coincida con unos criterios de búsqueda determinados. La aplicación usa una consulta LINQ para devolver las líneas del archivo que coinciden con los criterios especificados. Para consultar el contenido del archivo mediante una consulta LINQ, la aplicación puede cargar el contenido del archivo en una matriz o una colección. Sin embargo, al cargar el archivo completo en una matriz o colección se usaría mucha más memoria de la necesaria. En su lugar, la consulta LINQ podría consultar el contenido del archivo mediante una clase enumerable, lo que devolvería solamente los valores que coincidan con los criterios de búsqueda. Las consultas que solamente devuelven algunos valores coincidentes consumirían mucha 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 IEnumerable(T) requerirá otra clase que implemente la interfaz IEnumerator<T> para recorrer en iteración los datos de origen. Estas dos clases permiten devolver los elementos de datos secuencialmente como un tipo específico.
En este tutorial se creará una clase que implementa la interfaz IEnumerable(Of String) y otra que implementa la interfaz IEnumerator(Of String) para leer un archivo de texto de línea en línea.
Nota
Es posible que su equipo muestre nombres o ubicaciones diferentes para algunos de los elementos de la interfaz de usuario de Visual Studio incluidos en las instrucciones siguientes. 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 Valores de configuración de Visual Studio.
Crear la clase enumerable
Para crear el proyecto de clase enumerable
En el menú Archivo de Visual Basic, seleccione Nuevo y haga clic en Proyecto.
En el cuadro de diálogo Nuevo proyecto, en el recuadro Tipos de proyecto, asegúrese de haber seleccionado Windows. En el recuadro Plantillas, seleccione Biblioteca de clases. En el cuadro Nombre, escriba StreamReaderEnumerable y haga clic en Aceptar. Aparecerá el proyecto nuevo.
En el Explorador de soluciones, haga clic con el botón secundario del mouse en el archivo Class1.vb y haga clic en Cambiar nombre. Cambie el nombre del archivo a StreamReaderEnumerable.vb y presione ENTRAR. Al cambiar el nombre del archivo también se cambiará el nombre de la clase a StreamReaderEnumerable. Esta clase implementará la interfaz IEnumerable(Of String).
Haga clic con el botón secundario en el proyecto StreamReaderEnumerable, elija Agregar y 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 interfaz IEnumerable(Of String). Esta interfaz genérica implementa la interfaz IEnumerable y garantiza que los consumidores de esta clase puedan tener acceso a los valores de tipo String.
Para agregar el código para implementar IEnumerable
Abra el archivo StreamReaderEnumerable.vb.
En la línea situada detrás de Public Class StreamReaderEnumerable, escriba lo siguiente y presione ENTRAR.
Visual Basic rellena automáticamente la clase con los miembros que requiere la interfaz IEnumerable(Of String)
Esta clase enumerable leerá las líneas de un archivo de texto una a una. 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.
La implementación del método GetEnumerator de la interfaz IEnumerable(Of String) devolverá una nueva instancia de la clase StreamReaderEnumerator. La implementación del método GetEnumerator de la interfaz IEnumerable puede ser de tipo Private, dado que solo se tienen que exponer los miembros de la interfaz IEnumerable(Of String). Reemplace el código generado por Visual Basic para los métodos GetEnumerator con el siguiente código.
Visual Basic rellena automáticamente la clase con los miembros que requiere la interfaz IEnumerator(Of String)
La clase de enumerador abre el archivo de texto y realiza la E/S del archivo para leer las líneas de este. 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 abrir el archivo de texto para su lectura.
Las propiedades Current para las interfaces IEnumerator(Of String) e IEnumerator devuelven el elemento actual del archivo de texto como String. La implementación de la propiedad Current de la interfaz IEnumerator puede ser de tipo Private, dado que solo se tienen que exponer los miembros de la interfaz IEnumerator(Of String). Reemplace el código generado por Visual Basic para las propiedades Current con el siguiente código.
El método MoveNext de la interfaz IEnumerator navega al siguiente elemento del archivo de texto y actualiza el valor devuelto por la propiedad Current. Si no hay más elementos para leer, el método MoveNext devuelve False; de lo contrario, el método MoveNext devuelve True. Agregue el código siguiente al método MoveNext.
El método Reset de la interfaz IEnumerator dirige el iterador para que señale el inicio del archivo de texto y borra el valor del elemento actual. Agregue el código siguiente al método Reset.
El método Dispose de la interfaz IEnumerator garantiza la liberación de todos los recursos no administrados antes de destruirse el iterador. El identificador de archivo que usa el objeto StreamReader es un recurso no administrado y se debe cerrar antes de que se destruya la instancia del iterador. Reemplace el código generado por Visual Basic para el método Dispose con el siguiente código.
En el código, se puede usar una clase enumerable junto con las estructuras de control que requieren un objeto que implementa IEnumerable, como un bucle For Next o una consulta LINQ. En el ejemplo siguiente se muestra el objeto StreamReaderEnumerable en una consulta LINQ.
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()