Domanda
Oltre a (IEnumerable Returns GetEnumerator (), per " foreach " IEnumerble è essenziale)
quasi i seguenti due approcci ci consentono di scorrere la raccolta. Che cos'è
il vantaggio di uno rispetto all'altro? (Non sto chiedendo la differenza tra IEnumerable e IEnumerator).
static void Main()
{
IEnumerator<int> em = MyEnumerator<int>(new int[] { 1, 2, 3, 4 });
IEnumerator<int> e = Collection<int>
(new int[] { 1, 2, 3, 4 }).GetEnumerator();
while (em.MoveNext())
{
Console.WriteLine(em.Current);
}
while (e.MoveNext())
{
Console.WriteLine(e.Current);
}
Console.ReadKey(true);
}
approccio 1
public static IEnumerator<T> MyEnumerator<T>(T[] vals )
{
T[] some = vals;
foreach (var v in some)
{
yield return v;
}
}
approccio 2
public static IEnumerable<T> Collection<T>(T[] vals)
{
T[] some = vals;
foreach (var v in some)
{
yield return v;
}
}
Soluzione
La differenza principale è che la maggior parte delle API supporta un imput di IEnumerable<T>
ma non di IEnumerator<T>
.
Devi anche ricordare di chiamare Reset () quando lo usi mentre la sintassi è più evidente in GetEnumerator
(Chiama di nuovo RandomEnumerable
). Vedi anche il commento di Eric Lipper sul reset essendo una cattiva idea; se Reset non è implementato nel tuo RangeEnumerable
o è difettoso, diventa un enumeratore monouso (abbastanza inutile in molti casi).
Un'altra differenza potrebbe essere che potresti avere un Reset()
che può essere enumerato da più thread contemporaneamente ma un <=> archivia una posizione nei dati enumerati (Immagina un <=> o <=>).
Quindi la conclusione è che <=> è più versatile, ma comunque se hai una funzione che restituisce un <=> generando il <=> che lo circonda è semplice.
class EnumeratorWrapper<T> : IEnumerable<T>
{
Func<IEnumerator<T>> m_generator;
public EnumeratorWrapper(Func<IEnumerator<T>> generator)
{
m_generator = generator;
}
public IEnumerator<T> GetEnumerator()
{
return m_generator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return m_generator();
}
}
Solo per coerenza API usando <=> mi sembra la soluzione migliore.
Ma il problema con <=> in <=> lo rende comunque una soluzione inutilizzabile, quindi <=> è la strada da percorrere.
Altri suggerimenti
Correggimi se sbaglio, ma l'unica differenza è la differenza tra IEnumerable e IEnumerator e dato che hai specificamente detto che non stai chiedendo la differenza, entrambi sono un buon ...