Pergunta

Além de (IEnumerable retorna GetEnumerator (), para "foreach" IEnumerble é essencial)

quase duas abordagens nos permitem interagir sobre o collection.What é

a vantagem de um sobre o outro? (Não estou pedindo a diferença entre 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);
}

abordagem 1

 public static IEnumerator<T> MyEnumerator<T>(T[] vals )

 {
     T[] some = vals;

     foreach (var v in some)
     {
       yield return v;
     }
}

abordagem 2

public static IEnumerable<T> Collection<T>(T[] vals)
     {
         T[] some = vals;

         foreach (var v in some)
         {
             yield return v;
         }
     }
Foi útil?

Solução

A principal diferença é que o apoio mais API um imput de IEnumerable<T> mas não da IEnumerator<T>.

Você também tem que lembrar de chamar Reset () quando usá-lo, enquanto a sintaxe é mais evidente em IEnumerable<T> (Just chamada GetEnumerator novamente). ver também o comentário do Eric Lipper sobre redefinição de ser uma má idéia; Se Reiniciar não está implementado no seu IEnumerator<T> ou é buggy ele se torne um recenseador one-time-only (bastante inútil em muitos casos).

Outra diferença pode ser que você poderia ter um IEnumerable<T> que poderiam ser enumerados de vários segmentos ao mesmo tempo, mas uma posição de uma loja IEnumerator<T> nos dados enumerados (Imagine um RandomEnumerable ou RangeEnumerable).

Portanto, a conclusão é que IEnumerable<T> é mais versátil, mas de qualquer maneira, se você tem uma função retornando um IEnumerator<T> gerar o IEnumerable<T> em torno dele é simples.

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();
    }
}

Apenas para a consistência API usando IEnumerable<T> parece a melhor solução para mim.

Mas o problema com Reset() em IEnumerator<T> torná-lo uma solução inutilizável mesmo, então IEnumerable<T> é o caminho a percorrer.

Outras dicas

me corrija se eu estiver errado, mas a única diferença é a diferença entre IEnumerable e IEnumerator e desde que você disse especificamente que você não está fazendo a diferença, ambos são um bom ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top