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