IEnumerator 接口

定义

支持对非泛型集合的简单迭代。

public interface class IEnumerator
public interface IEnumerator
[System.Runtime.InteropServices.Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
public interface IEnumerator
[System.Runtime.InteropServices.Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
[System.Runtime.InteropServices.ComVisible(true)]
public interface IEnumerator
type IEnumerator = interface
[<System.Runtime.InteropServices.Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")>]
type IEnumerator = interface
[<System.Runtime.InteropServices.Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type IEnumerator = interface
Public Interface IEnumerator
派生
属性

示例

下面的代码示例演示自定义集合的 和 IEnumerator 接口的IEnumerable实现。 在此示例中,未显式调用这些接口的成员,但实现它们以支持使用 foreach Visual Basic 中的 (for each) 循环访问集合。

using System;
using System.Collections;

// Simple business object.
public class Person
{
    public Person(string fName, string lName)
    {
        this.firstName = fName;
        this.lastName = lName;
    }

    public string firstName;
    public string lastName;
}

// Collection of Person objects. This class
// implements IEnumerable so that it can be used
// with ForEach syntax.
public class People : IEnumerable
{
    private Person[] _people;
    public People(Person[] pArray)
    {
        _people = new Person[pArray.Length];

        for (int i = 0; i < pArray.Length; i++)
        {
            _people[i] = pArray[i];
        }
    }

// Implementation for the GetEnumerator method.
    IEnumerator IEnumerable.GetEnumerator()
    {
       return (IEnumerator) GetEnumerator();
    }

    public PeopleEnum GetEnumerator()
    {
        return new PeopleEnum(_people);
    }
}

// When you implement IEnumerable, you must also implement IEnumerator.
public class PeopleEnum : IEnumerator
{
    public Person[] _people;

    // Enumerators are positioned before the first element
    // until the first MoveNext() call.
    int position = -1;

    public PeopleEnum(Person[] list)
    {
        _people = list;
    }

    public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }

    public void Reset()
    {
        position = -1;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public Person Current
    {
        get
        {
            try
            {
                return _people[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}

class App
{
    static void Main()
    {
        Person[] peopleArray = new Person[3]
        {
            new Person("John", "Smith"),
            new Person("Jim", "Johnson"),
            new Person("Sue", "Rabon"),
        };

        People peopleList = new People(peopleArray);
        foreach (Person p in peopleList)
            Console.WriteLine(p.firstName + " " + p.lastName);
    }
}

/* This code produces output similar to the following:
 *
 * John Smith
 * Jim Johnson
 * Sue Rabon
 *
 */
Imports System.Collections

' Simple business object.
Public Class Person

    Public Sub New(ByVal fName As String, ByVal lName As String)
        Me.firstName = fName
        Me.lastName = lName
    End Sub


    Public firstName As String
    Public lastName As String
End Class

' Collection of Person objects, which implements IEnumerable so that
' it can be used with ForEach syntax.
Public Class People
    Implements IEnumerable

    Private _people() As Person

    Public Sub New(ByVal pArray() As Person)
        _people = New Person(pArray.Length - 1) {}

        Dim i As Integer
        For i = 0 To pArray.Length - 1
            _people(i) = pArray(i)
        Next i
    End Sub

    ' Implementation of GetEnumerator.
    Public Function GetEnumerator() As IEnumerator _
      Implements IEnumerable.GetEnumerator

        Return New PeopleEnum(_people)
    End Function

End Class

' When you implement IEnumerable, you must also implement IEnumerator.
Public Class PeopleEnum
    Implements IEnumerator

    Public _people() As Person

    ' Enumerators are positioned before the first element
    ' until the first MoveNext() call.
    Dim position As Integer = -1

    Public Sub New(ByVal list() As Person)
        _people = list
    End Sub

    Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
        position = position + 1
        Return (position < _people.Length)
    End Function

    Public Sub Reset() Implements IEnumerator.Reset
        position = -1
    End Sub

    Public ReadOnly Property Current() As Object Implements IEnumerator.Current
        Get
            Try
                Return _people(position)
            Catch ex As IndexOutOfRangeException
                Throw New InvalidOperationException()
            End Try
        End Get
    End Property
End Class

Class App
    Shared Sub Main()
        Dim peopleArray() As Person = { _
            New Person("John", "Smith"), _
            New Person("Jim", "Johnson"), _
            New Person("Sue", "Rabon")}

        Dim peopleList As New People(peopleArray)
        Dim p As Person
        For Each p In peopleList
            Console.WriteLine(p.firstName + " " + p.lastName)
        Next

    End Sub
End Class

' This code produces output similar to the following:
' 
' John Smith
' Jim Johnson
' Sue Rabon

注解

IEnumerator 是所有非泛型枚举器的基接口。 其泛型等效项是 System.Collections.Generic.IEnumerator<T> 接口。

C# 语言的 foreach 语句(在 Visual Basic 中为 for each)隐藏了枚举数的复杂性。 因此,建议使用 foreach 而不是直接操作枚举器。

枚举器可用于读取集合中的数据,但不能用于修改基础集合。

方法 Reset 为实现 COM 互操作性而提供,不需要完全实现;相反,实现者可能会引发 NotSupportedException

最初,枚举数定位在集合中第一个元素的前面。 在读取 的值Current之前,必须调用 MoveNext 方法以将枚举数推进到集合的第一个元素;否则为Current未定义。

在调用 CurrentMoveNext 之前,Reset 返回同一对象。 MoveNextCurrent 设置为下一个元素。

如果 MoveNext 传递集合的末尾,则枚举器位于集合中最后一个元素之后,并 MoveNext 返回 false。 当枚举器位于此位置时,对 MoveNext 的后续调用也会返回 false。 如果最后一次MoveNext调用返回 ,falseCurrent则为未定义。

若要再次设置为Current集合的第一个元素,可以调用 (如果已实现),然后调用 ResetMoveNext。 如果未 Reset 实现 ,则必须创建新的枚举器实例以返回到集合的第一个元素。

如果对集合进行了更改,例如添加、修改或删除元素,则枚举器的行为是不确定的。

枚举数没有对集合的独占访问权;因此,从头到尾对一个集合进行枚举在本质上不是一个线程安全的过程。 即使某个集合已同步,其他线程仍可以修改该集合,这会导致枚举数引发异常。 若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常。

属性

Current

获取集合中位于枚举数当前位置的元素。

方法

MoveNext()

将枚举数推进到集合的下一个元素。

Reset()

将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。

适用于

另请参阅