本文由机器翻译。若要查看英语原文,请勾选“英语”复选框。 也可将鼠标指针移到文本上,在弹出窗口中显示英语原文。
翻译
英语

IEnumerator 接口

 

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

命名空间:   System.Collections
程序集:  mscorlib(位于 mscorlib.dll)

[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
[ComVisibleAttribute(true)]
public interface IEnumerator

名称说明
System_CAPS_pubpropertyCurrent

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

名称说明
System_CAPS_pubmethodMoveNext()

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

System_CAPS_pubmethodReset()

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

IEnumerator 是所有非泛型枚举器的基接口。

有关此接口的泛型版本,请参阅IEnumerator<T>

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

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

Reset方法提供的 COM 互操作性和不需要完全实现; 相反,实施者可以引发NotSupportedException

最初,枚举数定位在集合中第一个元素的前面。 必须调用MoveNext方法将枚举数前移到集合,然后再读取的值的第一个元素Current; 否则为Current是不确定的。

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

如果MoveNext越过的末尾的集合,枚举数定位在集合中的最后一个元素的后面和MoveNext返回false 当枚举器位于此位置上,后续调用MoveNext还返回false 如果最后一次调用到MoveNext返回false,则调用Current将引发异常。

若要设置Current再次集合的第一个元素,可以调用Reset,如果它实现后, 跟MoveNext 如果Reset是未实现,你必须创建新的枚举器实例,以返回到集合的第一个元素。

只要集合保持不变,枚举数就保持有效。 如果对集合进行更改,例如添加、 修改或删除元素,则枚举数将失效且不可恢复失效,并且下次调用MoveNextReset引发InvalidOperationException 如果之间修改集合MoveNextCurrentCurrent返回到,设置的元素,即使枚举数已经无效。

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

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

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
 *
 */

通用 Windows 平台
自 8 起可用
.NET Framework
自 1.1 起可用
可移植类库
可移植 .NET 平台 中受支持
Silverlight
自 2.0 起可用
Windows Phone Silverlight
自 7.0 起可用
Windows Phone
自 8.1 起可用
返回页首
显示: