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


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. Если последний вызов MoveNext возвращен false, 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)

Применяется к

См. также раздел