Основным отличием является то, что большинство API поддерживают импульс IEnumerable<T>
, но не IEnumerator<T>
.
Вы также должны помнить, чтобы вызывать Reset () при его использовании, в то время как синтаксис более очевиден в IEnumerable<T>
(просто снова вызовите GetEnumerator
). Также см. Комментарий Эрика Липпера о том, что перезагрузка - плохая идея; если Reset не реализован в вашем IEnumerator<T>
или содержит ошибки, он становится одноразовым перечислителем (в большинстве случаев довольно бесполезным).
Другое отличие может заключаться в том, что вы можете иметь IEnumerable<T>
, который может быть перечислен из нескольких потоков одновременно, но IEnumerator<T>
сохранит одну позицию в перечисленных данных (представьте RandomEnumerable
или RangeEnumerable
).
Итак, вывод состоит в том, что IEnumerable<T>
более универсален, но в любом случае, если у вас есть функция, возвращающая IEnumerator<T>
, генерирующая IEnumerable<T>
вокруг нее, просто.
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();
}
}
Просто для согласованности API использование IEnumerable<T>
кажется лучшим решением для меня.
Но проблема с Reset()
в IEnumerator<T>
делает его в любом случае непригодным решением, поэтому IEnumerable<T>
- это путь.