Últimamente he estado leyendo artículos y documentación sobre ejecución diferida, LINQ, consultas en general, etc. y la frase "objeto está enumerado" aparecía con bastante frecuencia. ¿Alguien puede explicar qué sucede cuando se enumera un objeto?
Artículo de ejemplo.
Este método se implementa mediante el uso de ejecución diferida. El valor de retorno inmediato es un objeto que almacena toda la información que se requiere para realizar la acción. La consulta representada por este método no se ejecuta hasta que el objeto se enumera llamando directamente a su método GetEnumerator o usando foreach en Visual C#
IEnumerable es una interfaz, que generalmente se implementa mediante tipos de colección en C#. Por ejemplo, List , Queue o Array .
IEnumerable proporciona un método GetEnumerator que devuelve un objeto de tipo IEnumerator .
El IEnumerator básicamente representa un "puntero de avance" a los elementos de una colección. IEnumerator tiene:
Current , que devuelve el objeto al que apunta actualmente (por ejemplo, el primer objeto de su colección).MoveNext , que mueve el puntero al siguiente elemento. Después de llamarlo, Current mantendrá una referencia al segundo objeto de su colección. MoveNext devolverá false si no hubiera más elementos en la colección. Cada vez que se ejecuta un bucle foreach , se recupera el IEnumerator y se llama a MoveNext para cada iteración. La variable que define en el encabezado de su ciclo se llena con el ' Current ' de IEnumerator .
Gracias a @Llama
Este código...
List<int> a = new List<int>(); foreach (var val in a) { var b = 1 + val; }se transforma en algo como esto por el compilador:
List<int> list = new List<int>(); List<int>.Enumerator enumerator = list.GetEnumerator(); try { while (enumerator.MoveNext()) { int current = enumerator.Current; int num = 1 + current; } } finally { ((IDisposable)enumerator).Dispose(); } No hay garantía de que un foreach como resultado que se llame realmente a GetEnumerator ; sin embargo, es algo bastante común para el compilador.
La consulta representada por este método no se ejecuta hasta que el objeto se enumera llamando directamente a su método GetEnumerator o usando foreach en Visual C#.
Básicamente te dice todo ya. Creo que la confusión solo proviene de la falta de conocimiento sobre la enumeración. Tan pronto como alguien llama a GetEnumerator , se ejecuta el método. GetEnumerator se llama automáticamente, tan pronto como coloca su objeto en un bucle foreach .
Creo que solo necesita una buena comprensión de la ejecución diferida frente a la inmediata para las consultas LINQ.
Ejecución diferida : cuando escribe una consulta LINQ, solo se ejecuta cuando realmente accede a los resultados, diferida hasta que ejecuta el código para iterar, es decir, un foreach sobre los resultados. Este es el comportamiento estándar.
Ejecución inmediata : podemos forzar esto (que verá con frecuencia en el código C#) agregando un ToList() o un método similar a la consulta.