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 noto que IEnumerable tiene una versión genérica IEnumerable<T>, pero no puedo entender cómo implementarla.
Si agrego using System.Collections.Generic;a mis directivas de uso y luego cambio:
class MyObjects : IEnumerable
a:
class MyObjects : IEnumerable<MyObject>
Y luego haga clic derecho IEnumerable<MyObject>y seleccione Implement Interface => Implement Interface, Visual Studio agrega útilmente el siguiente bloque de código:
IEnumerator<MyObject> IEnumerable<MyObject>.GetEnumerator()
{
throw new NotImplementedException();
}
Devolver el objeto IEnumerable no genérico del GetEnumerator();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.

this.GetEnumerator()y simplemente regresarGetEnumerator()?Collection<MyObject>y luego no tendrá que escribir ningún código personalizado.List<T>e implementarIEnumerable<T>como se muestra en su respuesta.Probablemente no desee una implementación explícita de
IEnumerable<T>(que es lo que ha mostrado).El patrón habitual es usar
IEnumerable<T>'sGetEnumeratoren la implementación explícita deIEnumerable:fuente
IEnumerablees redundante (IEnumerable<T>ya se hereda de ella).¿Por qué lo haces manualmente?
yield returnautomatiza todo el proceso de manejo de iteradores. (También escribí sobre eso en mi blog , incluyendo un vistazo al código generado por el compilador).Si realmente desea hacerlo usted mismo, también debe devolver un enumerador genérico. Ya no podrá usar uno
ArrayListya que no es genérico. Cámbielo a unList<MyObject>lugar. Eso, por supuesto, supone que solo tiene objetos de tipoMyObject(o tipos derivados) en su colección.fuente
yield return. Asumí erróneamente que había un procesamiento personalizado.Si trabaja con genéricos, use List en lugar de ArrayList. La lista tiene exactamente el método GetEnumerator que necesita.
fuente
convertir mi lista en una
List<MyObject>, es una opciónfuente
Tenga en cuenta que el enfoque ya
IEnumerable<T>implementado porSystem.Collectionslo que otro enfoque es derivar suMyObjectsclaseSystem.Collectionscomo una clase base ( documentación ):Después podemos hacer nuestra propia implemenation para anular los virtuales
System.Collectionsmétodos para proporcionar un comportamiento personalizado (sólo paraClearItems,InsertItem,RemoveItem, ySetItemjunto con elEquals,GetHashCodeyToStringdesdeObject). A diferencia delList<T>que no está diseñado para ser fácilmente extensible.Ejemplo:
Tenga en cuenta que conducir
collectionsolo se recomienda en caso de que se necesite un comportamiento de recolección personalizado, lo que rara vez ocurre. ver uso .fuente