Существуют ли неповторяемые классы IEnumerable?

StackOverflow https://stackoverflow.com/questions/1814507

  •  06-07-2019
  •  | 
  •  

Вопрос

Есть ли неповторяемые классы IEnumerable?

Под неповторяемым я подразумеваю, когда вы не можете безопасно вызывать GetEnumerator несколько раз или когда вызов GetEnumerator имеет наблюдаемые побочные эффекты.

Это было полезно?

Решение

File.ReadLines() возвращает IEnumerable<T>, который работает только один раз.

Другие советы

Реализации IEnumerable (Of T) могут возвращать любые элементы, которые они считают нужными, по любой причине. Вполне ожидаемо, что если кто-то дважды вызовет GetEnumerator для одной и той же последовательности элементов, а затем перейдет к циклу между обоими перечислителями, они должны либо выдать одинаковые элементы в одном порядке, либо выдать исключение. Есть ряд подпрограмм, которые принимают IEnumerable (Of T) и будут плохо работать, если даны те, которые не соблюдают такой контракт.

Если бы у меня были мои барабанщики, IEnumerable был бы разделен на семейство интерфейсов; базовый перечислитель IEnumerable потерял бы метод Reset и не дал бы никаких конкретных обещаний повторяемости. Новый IMultiEnumerable возвращает перечислитель с методом Reset и гарантией того, что несколько проходов дадут одинаковые данные; перечислитель может также поддерживать свой собственный метод GetEnumerator (я думаю, что это должно быть практично для любого типа, который может поддерживать многопроходное перечисление; единственной ценой будет указатель 'start', поэтому вложенный перечислитель будет сброшен в исходное местоположение создание).

Нет, любой класс с хорошим поведением, который реализует IEnumerable, допускает повторные перечисления.

Для перечисления коллекций, которые не повторяются, у вас нет класса, реализующего GetEnumerator. Вместо этого у вас есть метод, который возвращает перечислитель. Таким образом, перечислитель вместо класса содержит коллекцию, поэтому невозможно вызвать Enumerable.Range дважды для одной и той же коллекции. Чтобы повторить перечислитель, вы должны вызвать метод для создания новой коллекции.

Примером этого является метод <=>. Он создает элементы для диапазона на лету, поэтому диапазон не существует как коллекция, что делает его неповторимым. Чтобы снова перечислить тот же диапазон, вы вызываете метод для создания нового диапазона с теми же границами.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top