В документации Microsoft для IEnumerable
[и IEnumerable<T>
-- неуниверсальные имена будут относиться к обоим] рекомендуется, чтобы каждый раз, когда объект, реализующий эти интерфейсы, изменялся, он делал недействительными все экземпляры IEnumerator
[IEnumerator<T>
], которые он создал ранее, заставляя их бросать InvalidOperationException
при последующих попытках доступа. Хотя ничто в документации Microsoft не задокументировало каких-либо изменений по сравнению с этой позицией, их фактическая реализация IEnumerable
, похоже, следует более свободному правилу, которое заключается в том, что IEnumerator
не должен вести себя бессмысленно, если базовая коллекция изменена; он должен выдать InvalidOperationException
если он не может вести себя "разумно". К сожалению, поскольку это правило не сформулировано явно, а скорее выведено из поведения их классов, неясно, что именно должно означать «разумное» поведение.
Все классы Microsoft, о которых я знаю, будут генерировать исключение при изменении коллекции, если они не соответствуют следующим критериям:
- Any item which exists unmodified throughout an enumeration will be returned exactly once.
- An item which is added or deleted during enumeration shall be returned at most once, but if an object is removed and re-added during enumeration, each re-addition may be regarded as creating a new "item".
- If a collection guarantees to return things in a sorted sequence, that guarantee must be met even if items are inserted and removed [e.g. if an "Fred" is added to an alphabetically-sorted list, and "George" has already been enumerated, "Fred" must not appear during that enumeration].
Было бы полезно, если бы были какие-то средства, с помощью которых коллекции могли бы сообщать, могут ли они удовлетворять вышеуказанным критериям (без создания исключений) даже при изменении, поскольку они могут быть очень полезны при попытке, например. удалить все элементы, соответствующие определенному критерию.
person
supercat
schedule
27.01.2013