Saltar al contenido

¿Alguien puede explicarme IEnumerable e IEnumerator?

Luego de de nuestra extensa búsqueda de datos resolvimos esta traba que presentan ciertos los usuarios. Te regalamos la solución y deseamos servirte de mucha apoyo.

Solución:

por ejemplo, ¿cuándo usarlo sobre foreach?

No usas IEnumerable “sobre” foreach. Implementar IEnumerable hace usar foreachposible.

Cuando escribe código como:

foreach (Foo bar in baz)

   ...

es funcionalmente equivalente a escribir:

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())

   bar = (Foo)bat.Current
   ...

Por “funcionalmente equivalente”, quiero decir que eso es en realidad en lo que el compilador convierte el código. No puedes usar foreach sobre baz en este ejemplo a no ser quebaz implementos IEnumerable.

IEnumerable significa que baz implementa el método

IEnumerator GetEnumerator()

los IEnumerator objeto que devuelve este método debe implementar los métodos

bool MoveNext()

y

Object Current()

El primer método avanza al siguiente objeto en el IEnumerable objeto que creó el enumerador, devolviendo false si está hecho, y el segundo devuelve el objeto actual.

Cualquier cosa en .Net que pueda iterar sobre los implementos IEnumerable. Si está creando su propia clase, y aún no hereda de una clase que implementa IEnumerable, puedes hacer que tu clase se pueda usar en foreach declaraciones implementando IEnumerable (y al crear una clase de enumerador que es nueva GetEnumerator volverá el método).

Las interfaces IEnumerable e IEnumerator

Para comenzar a examinar el proceso de implementación de interfaces .NET existentes, veamos primero el rol de IEnumerable e IEnumerator. Recuerde que C # admite una palabra clave denominada foreach que le permite iterar sobre el contenido de cualquier array escribe:

// Iterate over an array of items.
int[] myArrayOfInts = 10, 20, 30, 40;
foreach(int i in myArrayOfInts)

   Console.WriteLine(i);

Si bien puede parecer que solo array Los tipos pueden hacer uso de esta construcción, la verdad es que cualquier tipo que admita un método llamado GetEnumerator () puede ser evaluado por la construcción foreach. Para ilustrar, ¡sígueme!

Supongamos que tenemos una clase Garage:

// Garage contains a set of Car objects.
public class Garage

   private Car[] carArray = new Car[4];
   // Fill with some Car objects upon startup.
   public Garage()
   
      carArray[0] = new Car("Rusty", 30);
      carArray[1] = new Car("Clunker", 55);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   

Idealmente, sería conveniente iterar sobre los subelementos del objeto Garage usando la construcción foreach, al igual que un array de valores de datos:

// This seems reasonable ...
public class Program

   static void Main(string[] args)
   
      Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****n");
      Garage carLot = new Garage();
      // Hand over each car in the collection?
      foreach (Car c in carLot)
      
         Console.WriteLine("0 is going 1 MPH",
         c.PetName, c.CurrentSpeed);
      
      Console.ReadLine();
   

Lamentablemente, el compilador le informa que la clase Garage no implementa un método llamado GetEnumerator (). Este método está formalizado por la interfaz IEnumerable, que se encuentra al acecho dentro del espacio de nombres System.Collections. Las clases o estructuras que admiten este comportamiento anuncian que son capaces de exponer subelementos contenidos al llamador (en este ejemplo, la palabra clave foreach en sí). Aquí está la definición de esta interfaz .NET estándar:

// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable

   IEnumerator GetEnumerator();

Como puede ver, el método GetEnumerator () devuelve una referencia a otra interfaz más llamada System.Collections.IEnumerator. Esta interfaz proporciona la infraestructura para permitir que la persona que llama atraviese los objetos internos contenidos por el contenedor compatible con IEnumerable:

// This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator

   bool MoveNext (); // Advance the internal position of the cursor.
   object Current  get; // Get the current item (read-only property).
   void Reset (); // Reset the cursor before the first member.

Si desea actualizar el tipo de Garage para admitir estas interfaces, puede tomar el camino más largo e implementar cada método manualmente. Aunque sin duda tiene la libertad de proporcionar versiones personalizadas de GetEnumerator (), MoveNext (), Current y Reset (), existe una forma más sencilla. Como el tipo System.Array (así como muchas otras clases de colección) ya implementa IEnumerable e IEnumerator, simplemente puede delegar la solicitud al System.Array de la siguiente manera:

using System.Collections;
...
public class Garage : IEnumerable

   // System.Array already implements IEnumerator!
   private Car[] carArray = new Car[4];
   public Garage()
   
      carArray[0] = new Car("FeeFee", 200);
      carArray[1] = new Car("Clunker", 90);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   
   public IEnumerator GetEnumerator()
   
      // Return the array object's IEnumerator.
      return carArray.GetEnumerator();
   

Después de haber actualizado su tipo de Garage, puede usar el tipo de manera segura dentro de la construcción foreach de C #. Además, dado que el método GetEnumerator () se ha definido públicamente, el usuario del objeto también podría interactuar con el tipo IEnumerator:

// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("0 is going 1 MPH", myCar.PetName, myCar.CurrentSpeed);

Sin embargo, si prefiere ocultar la funcionalidad de IEnumerable del nivel de objeto, simplemente haga uso de la implementación de interfaz explícita:

IEnumerator IEnumerable.GetEnumerator()

  // Return the array object's IEnumerator.
  return carArray.GetEnumerator();

Al hacerlo, el usuario de objeto casual no encontrará el método GetEnumerator () de Garage, mientras que la construcción foreach obtendrá la interfaz en segundo plano cuando sea necesario.

Adaptado de Pro C # 5.0 y .NET 4.5 Framework

Implementar IEnumerable significa que su clase devuelve un objeto IEnumerator:

public class People : IEnumerable

    IEnumerator IEnumerable.GetEnumerator()
    
        // return a PeopleEnumerator
    

La implementación de IEnumerator significa que su clase devuelve los métodos y propiedades para la iteración:

public class PeopleEnumerator : IEnumerator

    public void Reset()...

    public bool MoveNext()...

    public object Current...

De todos modos, esa es la diferencia.

Te mostramos las reseñas y valoraciones de los lectores

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *