domingo, 17 de agosto de 2014

IEnumerable, Entendiendo las secuencias ...


La Iterface IEnumerable<T>, es una de las partes más importantes de todo el mundo de LinQ, ya que todos sus métodos extensores están realizados sobre este tipo y prácticamente todos ellos devuelven objetos de este mismo tipo.

 Podemos entenderla como la mínima expresión de una colección, y prácticamente la mayoría de las colecciones del Framework la implementan (List<T>, Observable<T>, Arrays, etc). En esta parte tenemos que indicar que hay una minoría de ellas que no lo hacen y que principalmente están formadas por colecciones especiales de controles gráficos, tales como el UIElementCollection que es la colección en la que se guardan los objetos contenidos dentro de un Grid de WPF. Cuando estemos acostumbrados a trabajar con LinQ y nos encontremos con una de estas colecciones, lo primero que pensaremos es que o nos falta algún using, o el intellisense o el propio Visual Studio nos están jugando una mala pasada. Un poco más adelante dentro del curso aprenderemos a convertirlas fácilmente en colecciones compatibles con la tecnología.





Recuerda que aquí tienes el indice de todos los posts del Curso de LinQ.



La documentación oficial dice simplemente que expone un Enumerador, el cual soporta una iteración sobre una colección de un tipo específico.

Vamos a ver la Interface un poco en profundidad:

  public interface IEnumerable<out T> : IEnumerable
  {
    IEnumerator<T> GetEnumerator();
  }

Como podemos apreciar la Interfaz es muy simple, y solo consta de un método GetEnumerator() que devuelve un objeto IEnumerator<T>, que a su vez implementa la interfaz IEnumerator, que nos proporciona la forma más simple de recorrer una colección y es la llave del uso del foreach.


public interface IEnumerator
  {
    object Current { get; }
    bool MoveNext();
    void Reset();
  }


Esta sería la forma más sencilla de recorrer una colección:

static void Main(string[] args)
{
    object[] nombres = { "nombre1", "nombre2", "nombreN" };
 
    IEnumerator enumerador = nombres.GetEnumerator();
 
    while(enumerador.MoveNext())
        Console.WriteLine(enumerador.Current);
 
    Console.Read();
}

Los iteradores, los veremos más en profundidad en la siguiente entrega Ejecución Diferida y la palabra reservada yield return.



La clase Enumerable

En este punto es importante hacer una reseña a esta clase estática que nos permite realizar una serie de acciones bastante prácticas sobre nuestros IEnumerable<T>.

Intanciar un IEnumerable<T> vacío:

IEnumerable<string> enumerableVacio = Enumerable.Empty<string>();


Crear colecciones con rangos de enteros:

IEnumerable<string> rango = Enumerable.Range(1, 1000);


Crear colecciones con valores de un tipo de objeto, repetidas:

IEnumerable<string> datosRepetidos = Enumerable.Repeat("Hola", 1000);