IEnumerable и IEnumerator.

В чём разница между этими интерфейсами и в каких случаях нужно использовать один, а в каких - другой?

По сути и один и другой предоставляет простой перебор по коллекции. Но различие между ними всё-же есть.

Интерфейс IEnumerable имеет метод, возвращающий ссылку на интерфейс IEnumerator, а именно на перечислитель, осуществляющий итерацию по коллекции. В IEnumerable мы имеем один единственный метод GetEnumerator.

Интерфейс IEnumerator определяет непосредственный перебор внутренних объектов в контейнере, а именно методы :

1) bool MoveNext(); - перемещение в контейнере на одну позицию вперёд

2) object Current { get; } - возвращает текущий элемент в контейнере

3) void Reset(); - перемещение в начало контейнера.