Поделиться через


Перечисление коллекции

Обновлен: Ноябрь 2007

В качестве простого способа перебора элементов коллекции платформа .NET Framework позволяет использовать механизм перечислителей. Перечислители могут лишь читать данные в коллекции; они не могут быть использованы для изменения коллекции, с которой они работают.

В некоторых языках существуют операторы, скрывающие сложности, связанные с непосредственным использованием перечислителей. Перечислители используются оператором языка C# foreach, оператором языка C++ for each и оператором языка Visual Basic For Each.

О перечислителях

Коллекции воспринимаются перечислителями таким образом, что доступ к их элементам может осуществляться последовательно. Различные классы коллекций могут иметь различный порядок следования элементов. Например, перечислитель для класса ArrayList сохраняет порядок, в котором элементы были введены в коллекцию, в то время как перечислитель для класса Hashtable перебирает элементы в соответствии с их хэш-кодом.

Все перечислители основаны на интерфейсе IEnumerator или на универсальном интерфейсе IEnumerator<T>, для чего им необходимо иметь перечисленные ниже члены.

  • Свойство Current указывает на текущий элемент коллекции.

  • Свойство MoveNext перемещает перечислитель к следующему элементу коллекции.

  • Свойство Reset перемещает перечислитель в начало коллекции. Свойство Current при этом указывает на положение перед первым элементом. В универсальном интерфейсе IEnumerator<T> свойство Reset отсутствует.

Поведение перечислителей

Изначально перечислитель располагается перед первым элементом коллекции. Свойство Reset также переводит перечислитель в это положение. В этом положении значение Current не определено. Поэтому до считывания значения свойства Current необходимо вызвать свойство MoveNext, чтобы переместить перечислитель на первый элемент коллекции.

Свойство Current возвращает один и тот же объект до тех пор, пока не вызваны свойства MoveNext или Reset. Свойство MoveNext переводит свойство Current к следующему элементу.

Если при вызове MoveNext перечислитель выходит за границы коллекции, то он помещается после последнего элемента в коллекции, а MoveNext возвращает значение false. Когда перечислитель находится в этой позиции, последующие вызовы MoveNext также возвращают значение false. Если последний вызов MoveNext вернул значение false, то значение Current не определено.

В неуниверсальных коллекциях для перемещения перечислителя обратно в начало можно вызвать Reset, а затем — MoveNext.

В универсальных коллекциях нельзя заново переместить свойство Current на первый элемент коллекции; вместо этого придется создать новый экземпляр перечислителя.

Перечислитель остается действительным, пока коллекция остается неизменной. Если в коллекцию были внесены изменения (например, производилось добавление, изменение или удаление элементов), то перечислитель становится недействительным и его поведение не определено.

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

См. также

Ссылки

IEnumerator

IEnumerator<T>

IDictionaryEnumerator

IEnumerable

IEnumerable<T>

Другие ресурсы

Управление коллекциями и их создание