IEnumerator<T> Интерфейс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Поддерживает простой перебор элементов универсальной коллекции.
generic <typename T>
public interface class IEnumerator : IDisposable, System::Collections::IEnumerator
public interface IEnumerator<out T> : IDisposable, System.Collections.IEnumerator
public interface IEnumerator<T> : IDisposable, System.Collections.IEnumerator
type IEnumerator<'T> = interface
interface IEnumerator
interface IDisposable
type IEnumerator<'T> = interface
interface IDisposable
interface IEnumerator
Public Interface IEnumerator(Of Out T)
Implements IDisposable, IEnumerator
Public Interface IEnumerator(Of T)
Implements IDisposable, IEnumerator
Параметры типа
- T
Тип объектов для перечисления.
Это ковариантный параметр типа. Это означает, что вы можете использовать любой из указанных типов или любой тип, являющийся более производным. Дополнительные сведения о ковариантности и контрвариантности см. в статье Ковариантность и контрвариантность в универсальных шаблонах.- Производный
- Реализации
Примеры
В следующем примере показана реализация IEnumerator<T> интерфейса для класса коллекции пользовательских объектов. Пользовательский объект является экземпляром типа Box
, а класс коллекции — BoxCollection
. Этот пример кода является частью более крупного примера, предоставленного ICollection<T> для интерфейса.
// Defines the enumerator for the Boxes collection.
// (Some prefer this class nested in the collection class.)
public class BoxEnumerator : IEnumerator<Box>
{
private BoxCollection _collection;
private int curIndex;
private Box curBox;
public BoxEnumerator(BoxCollection collection)
{
_collection = collection;
curIndex = -1;
curBox = default(Box);
}
public bool MoveNext()
{
//Avoids going beyond the end of the collection.
if (++curIndex >= _collection.Count)
{
return false;
}
else
{
// Set current box to next item in collection.
curBox = _collection[curIndex];
}
return true;
}
public void Reset() { curIndex = -1; }
void IDisposable.Dispose() { }
public Box Current
{
get { return curBox; }
}
object IEnumerator.Current
{
get { return Current; }
}
}
' Defines the enumerator for the Boxes collection.
' (Some prefer this class nested in the collection class.)
Public Class BoxEnumerator
Implements IEnumerator(Of Box)
Private _collection As BoxCollection
Private curIndex As Integer
Private curBox As Box
Public Sub New(ByVal collection As BoxCollection)
MyBase.New()
_collection = collection
curIndex = -1
curBox = Nothing
End Sub
Private Property Box As Box
Public Function MoveNext() As Boolean _
Implements IEnumerator(Of Box).MoveNext
curIndex = curIndex + 1
If curIndex = _collection.Count Then
' Avoids going beyond the end of the collection.
Return False
Else
'Set current box to next item in collection.
curBox = _collection(curIndex)
End If
Return True
End Function
Public Sub Reset() _
Implements IEnumerator(Of Box).Reset
curIndex = -1
End Sub
Public Sub Dispose() _
Implements IEnumerator(Of Box).Dispose
End Sub
Public ReadOnly Property Current() As Box _
Implements IEnumerator(Of Box).Current
Get
If curBox Is Nothing Then
Throw New InvalidOperationException()
End If
Return curBox
End Get
End Property
Private ReadOnly Property Current1() As Object _
Implements IEnumerator.Current
Get
Return Me.Current
End Get
End Property
End Class
' Defines two boxes as equal if they have the same dimensions.
Public Class BoxSameDimensions
Inherits EqualityComparer(Of Box)
Public Overrides Function Equals(ByVal b1 As Box, ByVal b2 As Box) As Boolean
If b1.Height = b2.Height And b1.Length = b2.Length And b1.Width = b2.Width Then
Return True
Else
Return False
End If
End Function
Public Overrides Function GetHashCode(ByVal bx As Box) As Integer
Dim hCode As Integer = bx.Height ^ bx.Length ^ bx.Width
Return hCode.GetHashCode()
End Function
End Class
Комментарии
IEnumerator<T> — базовый интерфейс для всех универсальных перечислителей.
Оператор foreach
языка C# (for each
в C++, For Each
в Visual Basic) скрывает сложность перечислителей. Поэтому рекомендуется вместо непосредственного использования перечислителя применять ключевое слово foreach
.
Перечислители могут использоваться для чтения данных в коллекции, но не для ее изменения.
Изначально перечислитель располагается перед первым элементом коллекции. В этой позиции значение свойства Current не определено. Поэтому необходимо вызвать метод MoveNext, чтобы переместить перечислитель к первому элементу коллекции до считывания значения свойства Current.
Current возвращает тот же объект, пока не будет вызван метод MoveNext. MoveNext задает Current в качестве значения для следующего элемента.
Если MoveNext передает конец коллекции, перечислитель позиционируется после последнего элемента в коллекции и MoveNext возвращает .false
Если перечислитель находится в этой позиции, последующие вызовы также MoveNext возвращаются false
. Если последний возвращенный false
вызов MoveNext не Current определен. Значение свойства Current не может быть повторно задано первому элементу коллекции; вместо этого следует создать новый экземпляр перечислителя.
Этот Reset метод предоставляется для взаимодействия COM. Он не обязательно должен быть реализован; вместо этого средство реализации может просто создать исключение NotSupportedException. Однако если вы решили сделать это, убедитесь, что вызывающие абоненты не полагаются на функциональные Reset возможности.
Если изменения вносятся в коллекцию, например добавление, изменение или удаление элементов, поведение перечислителя не определено.
У перечислителя нет эксклюзивного доступа к коллекции, поэтому перечисление коллекции не является потокобезопасной процедурой. Чтобы гарантировать потокобезопасность, можно заблокировать коллекцию на время всего перечисления. Чтобы разрешить доступ к коллекции из нескольких потоков для чтения и записи, необходимо реализовать собственную синхронизацию.
Используемые по умолчанию реализации коллекций в пространстве имен System.Collections.Generic не синхронизированы.
Примечания для тех, кто реализует этот метод
Реализация этого интерфейса требует реализации негенерического IEnumerator интерфейса. Методы MoveNext() и Reset() методы не зависят от T
и отображаются только в негенерическом интерфейсе. Свойство Current отображается в обоих интерфейсах и имеет разные типы возвращаемых значений. Реализуйте негенерическое Current свойство в виде явной реализации интерфейса. Это позволяет любому потребителю негенерного интерфейса использовать универсальный интерфейс.
Кроме того, IEnumerator<T> реализуется IDisposable, который требует реализации Dispose() метода. Это позволяет закрыть подключения к базе данных или дескрипторы файлов выпуска или аналогичные операции при использовании других ресурсов. Если нет дополнительных ресурсов для удаления, предоставьте пустую Dispose() реализацию.
Свойства
Current |
Возвращает элемент коллекции, соответствующий текущей позиции перечислителя. |
Методы
Dispose() |
Выполняет определяемые приложением задачи, связанные с удалением, высвобождением или сбросом неуправляемых ресурсов. (Унаследовано от IDisposable) |
MoveNext() |
Перемещает перечислитель к следующему элементу коллекции. (Унаследовано от IEnumerator) |
Reset() |
Устанавливает перечислитель в его начальное положение, т. е. перед первым элементом коллекции. (Унаследовано от IEnumerator) |