C'è qualche differenza tra i metodi iteratori che restituiscono IEnumerable < T > e IEnumerator < T > ;?
Domanda
Prendi in considerazione due metodi iteratori con gli stessi corpi:
public static IEnumerable<int> It1() {
...
}
public static IEnumerator<int> It2() {
...
}
Esistono circostanze in cui la chiamata It2
è diversa dalla chiamata It1.GetEnumerator ()
?
C'è mai una buona ragione per definire un iteratore come IEnumerator < T >
su IEnumerable < T >
? L'unico che mi viene in mente è quando stai implementando IEnumerable < T > .GetEnumerator ()
.
EDIT: per metodi iteratore intendo metodi che usano i costrutti yield return
e yield break
.
Soluzione
Lo faresti se volessi occuparti della scrittura della classe wrapper IEnumerable < T >
.
Diciamo che hai una classe su cui vuoi fare l'enumerazione, all'infinito:
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);
}
}
}
Altri suggerimenti
Come notato, non puoi foreach
su un IEnumerator < T >
. Per questo motivo, rende difficile l'integrazione in posizioni nel codice in cui si desidera scorrere su ciò che si sta restituendo.
Inoltre, l'importanza qui è che IEnumerable < T >
è pensato per essere una fabbrica, in modo che tu possa produrre implementazioni di IEnumerator < T >
che non lo sono direttamente legato all'implementazione della raccolta di T
.
Ancora più importante ora è il fatto che tutti i metodi di estensione per LINQ funzionano con IEnumerable < T >
, quindi vorrai rendere le tue enumerazioni il più facili da utilizzare possibile restituendole.