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;
         }
     }
È stato utile?

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 ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top