entre - qué es IEnumerable en.net
list ienumerable c# (5)
¿Qué es IEnumerable en .net?
Es una interfaz implementada por los tipos Collection en .NET que proporcionan el patrón Iterator . También existe la versión genérica que es IEnumerable<T>
.
La sintaxis (que rara vez se ve porque hay formas más bonitas de hacerlo) para moverse a través de una colección que implementa IEnumerable es:
IEnumerator enumerator = collection.GetEnumerator();
while(enumerator.MoveNext())
{
object obj = enumerator.Current;
// work with the object
}
Que es funcionalmente equivalente a:
foreach(object obj in collection)
{
// work with the object
}
Si la colección admite indexadores, también podría iterar sobre ella con el método clásico de bucle pero el patrón Iterator proporciona algunos extras interesantes, como la capacidad de agregar sincronización para enhebrar.
La respuesta corta es que es algo en lo que puedes usar un foreach
.
Primero es una interfaz. La definición según MSDN es
Expone el enumerador, que admite una iteración simple sobre una colección no genérica.
Dicho de una manera muy simple, que cualquier objeto que implemente esta interfaz proporcionará una forma de obtener un enumerador. Un enumerador se usa con el foreach
como un ejemplo.
Una lista implementa la interfaz IEnumerable.
// This is a collection that eventually we will use an Enumertor to loop through
// rather than a typical index number if we used a for loop.
List<string> dinosaurs = new List<string>();
dinosaurs.Add("Tyrannosaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("Mamenchisaurus");
dinosaurs.Add("Deinonychus");
dinosaurs.Add("Compsognathus");
Console.WriteLine();
// HERE is where the Enumerator is gotten from the List<string> object
foreach(string dinosaur in dinosaurs)
{
Console.WriteLine(dinosaur);
}
// You could do a
for(int i = 0; i < dinosaurs.Count; i++)
{
string dinosaur = dinosaurs[i];
Console.WriteLine(dinosaur);
}
El foreach se ve más limpio.
Es ... algo ... que puedes repetir. Eso podría ser una lista o una matriz o (casi) cualquier otra cosa que sea compatible con un bucle foreach
. Es para cuando quieres poder usar un objeto con un ciclo foreach
, pero no sabes exactamente de qué tipo estás tratando, ya sea Matriz, Lista o algo personalizado.
Esa es la primera ventaja: si sus métodos aceptan un IEnumerable en lugar de una matriz o lista, se vuelven más potentes porque puede pasarles más tipos diferentes de objetos.
Ahora lo que hace que IEnumerable realmente se destaque son los bloques de iteradores (la palabra clave yield
en C #). Los bloques Iterator implementan la interfaz IEnumerable como una Lista o una Matriz, pero son muy especiales porque a diferencia de una Lista o Matriz, a menudo solo retienen el estado para un solo elemento a la vez. Por lo tanto, si desea recorrer las líneas en un archivo muy grande, por ejemplo, puede escribir un bloque de iteradores para manejar la entrada del archivo. Entonces nunca tendrá más de una línea del archivo en la memoria a la vez, y si termina el ciclo antes (tal vez fue una búsqueda y encontró lo que necesitaba) es posible que no necesite leer todo el archivo. O si está leyendo los resultados de una gran consulta SQL, puede limitar el uso de su memoria a un único registro.
Otra característica es que esta evaluación es floja , por lo que si está haciendo un trabajo complicado para evaluar el enumerable a medida que lee de él, ese trabajo no ocurre hasta que se lo solicite. Esto es más beneficioso, porque a menudo (por ejemplo, para las búsquedas de nuevo) encontrará que no necesita hacer el trabajo en absoluto.
Puede pensar en IEnumerable como si fuera una Lista just-in-time.
using System.Collections;
using static System.Console;
namespace SimpleIterators
{
class X
{
static int i = 0;
public int I
{
get { return i; }
}
public X()
{
WriteLine("X "+i++);
}
}
class Program
{
public static IEnumerable ValueI(X[] tabl)
{
for (int i = 0; i < 10; i++)
yield return tabl[i].I;
}
public static IEnumerable ListClass(X[] tabl)
{
for (int i = 0; i < 10; i++)
yield return tabl[i] = new X();
}
static void Main(string[] args)
{
X[] tabl = new X[10];
foreach (X x in ListClass(tabl));
foreach (int i in ValueI(tabl))
WriteLine("X " + i);
WriteLine("X " + tabl[0].I);
ReadKey();
}
}
}