Все мы знаем, что цикл foreach
был разработан для чтения коллекции, а не для записи в нее.
Вот почему следующее приводит к InvalidOperationException
:
Как он отслеживает изменения в коллекции?
Это делается с помощью int с именем _version
в классе List<T>
.
_version
увеличивается каждый раз при обновлении коллекции, то есть в следующих методах:
- Метод установки индексатора
Add()
Clear()
Insert()
InsertRange()
RemoveAll()
RemoveAt()
RemoveRange()
Reverse()
Sort()
Когда List<T>
перечисляется в foreach
, вызывается метод GetEnumerator()
, который возвращает экземпляр структуры с именем Enumerator
.
Enumerator
имеет свою собственную переменную version
, которая инициализируется только один раз со значением из List<T>._version
и никогда не изменяется.
Во время каждой итерации в foreach
вызывается метод MoveNext()
, который проверяет, совпадает ли List<T>._version
с version
.
Если они не совпадают, генерируется исключение:
Прочтите эту статью, чтобы узнать интересный способ обойти это исключение.