foreach
построен поверх IEnumerable<T>
Контракт для счетчика на MSDN говорит
Изначально перечислитель располагается перед первым элементом в коллекции. ... Следовательно, вы должны вызвать MoveNext, чтобы перевести перечислитель в первый элемент коллекции, прежде чем читать значение Current.
Current возвращает тот же объект, пока не будет вызван MoveNext. MoveNext устанавливает Current для следующего элемента.
Таким образом, если базовая коллекция имеет четкий «первый» элемент, а каждый элемент имеет четкий «следующий» элемент, как в случае массивов, списков и т. Д., То можно ожидать, что foreach
будет вести себя логически и стабильно. Если это что-то вроде набора, который не имеет первой или следующей последовательности, то он может вести себя нестабильно, хотя, предположительно, без изменения состояния IEnumerable, даже коллекции, которые не имеют определенного порядка, будут непротиворечивыми, поскольку их несогласованность будет более Работа!