2009-01-06 7 views
7

considerar dos métodos de iterador con los mismos cuerpos:¿Hay alguna diferencia entre los métodos del iterador que devuelven IEnumerable <T> y IEnumerator <T>?

public static IEnumerable<int> It1() { 
    ... 
} 

public static IEnumerator<int> It2() { 
    ... 
} 

¿Hay alguna circunstancia en la que llamar It2 es diferente de llamar It1.GetEnumerator()?

¿Hay alguna vez una buena razón para definir un iterador como IEnumerator<T> sobre IEnumerable<T>? El único en el que puedo pensar es cuando está implementando IEnumerable<T>.GetEnumerator().

EDITAR: Por métodos de iterador me refiero a los métodos que usan constructos yield return y yield break.

+0

implementaciones sentido estricto de métodos no pueden ser iguales. –

+0

Por supuesto que sí. public static IEnumerable It1() { yield return 1; } public static IEnumerator It2() { yield return 1; } –

+0

Ahora, lo que el compilador los convierte en obviamente difiere; uno se convierte en una clase anónima que implementa IEnumerator y el otro en dos clases anónimas que implementan IEnumerable e IEnumerator . ¿Hay algún caso cuando los dos IEnumerators son diferentes? –

Respuesta

1

Lo haría si quisiera hacerse cargo de escribir la clase de contenedor IEnumerable<T>.

Digamos que usted tiene una clase que desea hacer la enumeración en, infinitamente:

public class EveryDateInTheFuture : IEnumerable<DateTime> 
{ 
    public EveryDateInTheFuture() { this.StartDate = DateTime.Today; } 

    public DateTime StartDate { get; set; } 

    public IEnumerator<DateTime> GetEnumerator() 
    { 
     while (true) 
     { 
      yield return date; 
      date = date.AddDays(1); 
     } 
    } 
} 
8

Según lo observado, no puedes foreach sobre IEnumerator<T>. Debido a eso, dificulta la integración en lugares en el código donde desea iterar sobre lo que está devolviendo.

Además, el imporance aquí es que IEnumerable<T> está destinado a ser una fábrica, por lo que se puede producir implementaciones de IEnumerator<T> que no están directamente vinculados a la aplicación de la colección de T.

Aún más importante ahora es el hecho de que todos los métodos de extensión para LINQ funcionan desde IEnumerable<T>, por lo que querrá hacer que sus enumeraciones sean tan fáciles de trabajar como sea posible devolviéndolas.

+0

Sí, esas son todas buenas razones para preferir IEnumerable sobre IEnumerator . Es por eso que pregunté sobre la dirección opuesta. –

Cuestiones relacionadas