programacion lenguaje for espaƱol comandos codigos basicos avanzada c# .net iterator generator enumeration

for - lenguaje c#



DistinciĆ³n entre iterador y enumerador (8)

"Los iteradores son una característica nueva en C # 2.0. Un iterador es un método, obtiene un acceso o un operador que le permite admitir la iteración foreach en una clase o estructura sin tener que implementar toda la interfaz IEnumerable. En su lugar, proporciona solo un iterador, que simplemente atraviesa las estructuras de datos de su clase. Cuando el compilador detecte su iterador, generará automáticamente los métodos Current, MoveNext y Dispose de la interfaz IEnumerable o IEnumerable. " - msdn

Una pregunta de entrevista para un trabajo de .NET 3.5 es "¿Cuál es la diferencia entre un iterador y un enumerador"?

Esta es una distinción esencial para hacer, con LINQ, etc.

De todos modos, ¿cuál es la diferencia? Parece que no puedo encontrar una definición sólida en la red. No se equivoquen, puedo encontrar el significado de los dos términos pero obtengo respuestas ligeramente diferentes. ¿Cuál sería la mejor respuesta para una entrevista?

IMO un iterador "itera" sobre una colección, y un enumerador proporciona la funcionalidad para iterar, pero esto tiene que ser llamado.

Además, usar la palabra clave yield se dice que salva el estado. ¿Qué es exactamente este estado? ¿Hay algún ejemplo de este beneficio?


"Mientras que un enunciado foreach es el consumidor del enumerador, un iterador es el productor del enumerador".

Lo anterior es cómo lo explica "C # 5.0 In A NutShell" y me ha sido útil.

En otras palabras, la instrucción foreach usa MoveNext () y la propiedad Current del IEnumerator para iterar a través de una secuencia, mientras que el iterador se usa para producir la implementación del IEnumerator que utilizará la instrucción foreach. En C #, cuando escribe un método de iterador que contiene una declaración de rendimiento, el compilador generará un enumerador privado para usted. Y cuando repite los elementos en la secuencia, llamará a la propiedad MoveNext () y Current del enumerador privado. Estos métodos / propiedades son implementados por su código en el método del iterador que se llamará repetidamente para producir valores hasta que no queden valores para ceder.

Esta es mi comprensión de cómo C # define enumeradores e iteradores.


Como no se dieron ejemplos, aquí hay uno que fue útil para mí.

Un enumerador es un objeto que obtienes cuando llamas a .GetEnumerator () en una clase o tipo que implementa la interfaz de IEnumerator. Cuando se implementa esta interfaz, ha creado todo el código necesario para que el compilador le permita utilizar foreach para "iterar" sobre su colección.

Sin embargo, la palabra "iterar" no se confunde con el iterador. Tanto el Enumerador como el iterador le permiten "iterar". Enumerar e iterar son básicamente el mismo proceso, pero se implementan de manera diferente. Enumerar significa que ha implementado la interfaz IEnumerator La iteración significa que ha creado el constructo iterador en su clase (que se muestra a continuación), y está llamando a foreach en su clase, en cuyo momento el compilador crea automáticamente la funcionalidad del enumerador para usted.

También tenga en cuenta que no tiene que hacer sentadillas con su enumerador. Puede llamar a MyClass.GetEnumerator() todo el día y no hacer nada con él (ejemplo:

IEnumerator myEnumeratorThatIWillDoNothingWith = MyClass.GetEnumerator() ).

Tenga en cuenta también que la construcción de su iterador en su clase solo se usa realmente cuando realmente la está usando, es decir, que ha llamado a foreach en su clase.

Aquí hay un ejemplo de iterador de msdn :

public class DaysOfTheWeek : System.Collections.IEnumerable { string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; //This is the iterator!!! public System.Collections.IEnumerator GetEnumerator() { for (int i = 0; i < days.Length; i++) { yield return days[i]; } } } class TestDaysOfTheWeek { static void Main() { // Create an instance of the collection class DaysOfTheWeek week = new DaysOfTheWeek(); // Iterate with foreach - this is using the iterator!!! When the compiler //detects your iterator, it will automatically generate the Current, //MoveNext and Dispose methods of the IEnumerator or IEnumerator<T> interface foreach (string day in week) { System.Console.Write(day + " "); } } } // Output: Sun Mon Tue Wed Thr Fri Sat


En C # 2+, los iterators son una forma para que el compilador genere automáticamente las interfaces IEnumerable y / o IEnumerable <T> por usted.

Sin iteradores, necesitaría crear una clase que implementara IEnumerator , incluyendo Current, MoveNext y Reset. Esto requiere una buena cantidad de trabajo. Normalmente, crearía una clase privada que implementara IEnumerator <T> para su tipo, luego yourClass.GetEnumerator () construiría esa clase privada y la devolvería.

Los iteradores son una forma para que el compilador genere automáticamente esto para usted, usando una sintaxis simple (rendimiento). Esto le permite implementar GetEnumerator () directamente en su clase, sin que usted especifique una segunda clase (The IEnumerator). La construcción de esa clase, con todos sus miembros, está hecha para ti.

Los iteradores son muy amigables con los desarrolladores: las cosas se hacen de una manera muy eficiente, con mucho menos esfuerzo.

Cuando utiliza foreach, los dos se comportarán de manera idéntica (siempre que escriba su IEnumerator personalizado correctamente). Los iteradores simplemente hacen la vida mucho más simple.


Iterar significa repetir algunos pasos, mientras que enumerar significa pasar por todos los valores en una colección de valores. Por lo tanto, enumerar generalmente requiere alguna forma de iteración.

De esa forma, enumerar es un caso especial de iteración donde el paso obtiene un valor de una colección.

Nótese el "por lo general": la enumeración también puede realizarse recursivamente, pero la recursión y la iteración están tan estrechamente relacionadas que no me interesaría esta pequeña diferencia.

También puede enumerar valores que no almacena explícitamente en una colección. Por ejemplo, puede enumerar el número natural, los números primos o lo que sea, pero usted calcularía estos valores durante la enumeración y no los recuperaría de una colección física. Comprende este caso como la enumeración de una colección virtual con sus valores definidos por alguna lógica.

Supongo que Reed Copsey entendió el punto. En C # hay dos formas principales de enumerar algo.

  1. Implementar Enumerable y una clase implementando IEnumerator
  2. Implementar un iterador con la declaración de yield

La primera forma es más difícil de implementar y usa objetos para enumerar. La segunda forma es más fácil de implementar y usa continuaciones.


La enumeración se ocupa de los objetos mientras que la iteración trata solo con los valores. La enumeración se usa cuando usamos tablas de vectores, etc., mientras que las iteraciones se usan en ciclos de while para loop, etc. Nunca utilicé la palabra clave yield, así que no pude decírtelo.


Lo que C # llama un iterador es más comúnmente (fuera del mundo de C #) llamado generator o función del generador (por ejemplo, en Python). Una función de generador es un caso especializado de coroutine . El iterador de CA # (generador) es una forma especial de un enumerador (un tipo de datos que implementa la interfaz IEnumerable ).

No me gusta este uso del término iterador para un generador de C # porque es tanto un enumerador como un iterador. Demasiado tarde para que Microsoft cambie de opinión.

Por contraste, considere que en C ++ un iterador es un valor que se usa principalmente para acceder a elementos secuenciales en una colección. Puede avanzarse, derivarse para recuperar un valor y probarse para ver si se ha alcanzado el final de la colección.


Para comprender los iteradores, primero debemos comprender los enumeradores.

Los enumeradores son objetos especializados que le proporcionan a uno los medios para moverse a través de una lista ordenada de elementos de a uno por vez (el mismo tipo de cosas a veces se denomina ''cursor''). .NET Framework proporciona dos interfaces importantes relacionadas con los enumeradores: IEnumerator e IEnumerable. Los objetos que implementan IEnumerator son en sí mismos enumeradores; Ellos apoyan a los siguientes miembros:

  • la propiedad Actual, que apunta a un puesto en la lista

  • el método MoveNext, que mueve el elemento actual uno a lo largo de la lista

  • el método Restablecer, que mueve el elemento actual a su posición inicial (que está antes del primer elemento).

Por otro lado, los Iteradores implementan el modelo del enumerador. .NET 2.0 introdujo el iterador, que es un enumerador en lenguaje compilador. Cuando el objeto englobable recibe GetEnumerator, ya sea directa o indirectamente, el compilador genera y devuelve un objeto iterador apropiado. Opcionalmente, el iterador puede ser un objeto combinado enumerrable y enumerador.

El ingrediente esencial de un bloque de iterador es el rendimiento. Hay una gran diferencia entre los iteradores y los enumeradores: los Iteradores no implementan el método Restablecer. Al ejecutar el método Restablecer en un iterador se produce una excepción.

El objetivo de los iteradores es permitir la fácil implementación de los enumeradores. Cuando un método necesita devolver un enumerador o una clase enumerable para una lista ordenada de elementos, se escribe para devolver cada artículo en el orden correcto usando la instrucción ''yield''.