item - read ienumerable c#
¿Cómo implemento IEnumerable<T> (5)
¿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 compilador).
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<MyObject>
lugar. Por supuesto, eso supone que solo tiene objetos de tipo MyObject
(o tipos derivados) en su colección.
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<T>
, 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<MyObject>
Y luego, haga clic derecho en 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 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.
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>
en la implementación explícita de IEnumerable:
class FooCollection : IEnumerable<Foo>, IEnumerable
{
SomeCollection<Foo> foos;
// Explicit for IEnumerable because weakly typed collections are Bad
System.Collections.IEnumerator IEnumerable.GetEnumerator()
{
// uses the strongly typed IEnumerable<T> implementation
return this.GetEnumerator();
}
// Normal implementation for IEnumerable<T>
IEnumerator<Foo> 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<T> or T[], your choice.
}
// or, as pointed out: return this.foos.GetEnumerator();
}
}
Si elige usar una colección genérica, como List<MyObject>
lugar de ArrayList
, encontrará que List<MyObject>
proporcionará enumeradores genéricos y no genéricos que puede usar.
using System.Collections;
class MyObjects : IEnumerable<MyObject>
{
List<MyObject> mylist = new List<MyObject>();
public MyObject this[int index]
{
get { return mylist[index]; }
set { mylist.Insert(index, value); }
}
public IEnumerator<MyObject> GetEnumerator()
{
return mylist.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Si trabaja con genéricos, use List en lugar de ArrayList. La Lista tiene exactamente el método GetEnumerator que necesita.
List<MyObject> myList = new List<MyObject>();
hacer mylist en una List<MyObject>
, es una opción