¿Cómo implemento IEnumerable

Sé cómo implementar el IEnumerable no genérico, así:

using System; using System.Collections; namespace ConsoleApplication33 { class Program { static void Main(string[] args) { MyObjects myObjects = new MyObjects(); myObjects[0] = new MyObject() { Foo = "Hello", Bar = 1 }; myObjects[1] = new MyObject() { Foo = "World", Bar = 2 }; foreach (MyObject x in myObjects) { Console.WriteLine(x.Foo); Console.WriteLine(x.Bar); } Console.ReadLine(); } } class MyObject { public string Foo { get; set; } public int Bar { get; set; } } class MyObjects : IEnumerable { ArrayList mylist = new ArrayList(); public MyObject this[int index] { get { return (MyObject)mylist[index]; } set { mylist.Insert(index, value); } } IEnumerator IEnumerable.GetEnumerator() { return mylist.GetEnumerator(); } } } 

Sin embargo, también noté que IEnumerable tiene una versión genérica, IEnumerable , pero no puedo encontrar la manera de implementarlo.

Si agrego using System.Collections.Generic; a mis directivas de uso, y luego cambiar:

 class MyObjects : IEnumerable 

a:

 class MyObjects : IEnumerable 

Y luego, haga clic derecho en IEnumerable y seleccione Implement Interface => Implement Interface , Visual Studio agrega útilmente el siguiente bloque de código:

 IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } 

Devolver el objeto IEnumerable no genérico de GetEnumerator(); El método no funciona esta vez, entonces ¿qué pongo aquí? La CLI ahora ignora la implementación no genérica y se dirige directamente a la versión genérica cuando intenta enumerar a través de mi matriz durante el ciclo foreach.

Si elige usar una colección genérica, como List lugar de ArrayList , encontrará que List proporcionará enumeradores generics y no generics que puede usar.

 using System.Collections; class MyObjects : IEnumerable { List mylist = new List(); public MyObject this[int index] { get { return mylist[index]; } set { mylist.Insert(index, value); } } public IEnumerator GetEnumerator() { return mylist.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } 

Probablemente no desee una implementación explícita de IEnumerable (que es lo que ha mostrado).

El patrón habitual es usar IEnumerable en la implementación explícita de IEnumerable:

 class FooCollection : IEnumerable, IEnumerable { SomeCollection foos; // Explicit for IEnumerable because weakly typed collections are Bad System.Collections.IEnumerator IEnumerable.GetEnumerator() { // uses the strongly typed IEnumerable implementation return this.GetEnumerator(); } // Normal implementation for IEnumerable IEnumerator GetEnumerator() { foreach (Foo foo in this.foos) { yield return foo; //nb: if SomeCollection is not strongly-typed use a cast: // yield return (Foo)foo; // Or better yet, switch to an internal collection which is // strongly-typed. Such as List or T[], your choice. } // or, as pointed out: return this.foos.GetEnumerator(); } } 

¿Por qué lo haces manualmente? yield return automatiza todo el proceso de manejo de iteradores. (También escribí sobre esto en mi blog , incluyendo un vistazo al código generado por el comstackdor).

Si realmente desea hacerlo usted mismo, también debe devolver un enumerador genérico. Ya no podrá usar un ArrayList ya que no es genérico. Cambie a una List lugar. Por supuesto, eso supone que solo tiene objetos de tipo MyObject (o tipos derivados) en su colección.

Si trabaja con generics, use List en lugar de ArrayList. La Lista tiene exactamente el método GetEnumerator que necesita.

 List myList = new List(); 

hacer mylist en una List , es una opción