Некоторое время назад я написал метод расширения IList
для перечисления части списка с использованием индексов. Во время рефакторинга я понял, что аналогичный запрос можно выполнить, вызвав Skip(toSkip).Take(amount)
. При тестировании я заметил, что Skip
не оптимизирован для IList
. Немного погуглив, я наткнулся на пост Джона Скита, обсуждение того, почему такие методы оптимизации, как Skip
, опасны.
Насколько я понимаю в статье, проблема не в том, что исключение возникает в оптимизированных методах при изменении коллекции, но, как говорится в комментарии, документация msdn конфликтует сама с собой.
Если в коллекцию вносятся изменения, такие как добавление, изменение или удаление элементов, перечислитель безвозвратно становится недействительным, а следующий вызов MoveNext или Reset выдает исключение InvalidOperationException.
В IEnumerator.GetEnumerator():
Если в коллекцию вносятся изменения, такие как добавление, изменение или удаление элементов, перечислитель безвозвратно становится недействительным, и его поведение не определено.
Я вижу достоинства в обоих соглашениях и немного теряюсь, стоит ли их оптимизировать. Что такое правильное решение? Я рассматривал подход IList.AssumeImmutable()
в духе AsParallel()
, как упоминал Крис Вандермоттен в комментариях. Какая-то реализация уже существует или это плохая идея?
Skip
и т. д. будет ошибкой, и у него есть абзац, объясняющий, почему... тогда я расценю это как хорошее рассуждение. - person Marc Gravell   schedule 03.05.2011ItemsInRange(Lo, Hi)
без использованияSkip/Take
. - person Rafe   schedule 03.05.2011ItemsInRange
должен существовать и дляIEnumerable
, и это вызовет исключение, поэтому версияIList
не может быть оптимизирована аргументом Джона. - person Rick Sladkey   schedule 03.05.2011