/*语法:(C#)*/
[ComVisibleAttribute(true)] 
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")] 
public interface IEnumerator


 备注:

    

/*
     IEnumerator 是所有非泛型枚举数的基接口。
     C# 语言的 foreach 语句(在 Visual Basic 中为 for each)隐藏了枚举数的复杂性。因此,建议  foreach,而不直接操作枚举数。枚举数可用于读取集合中的数据,但不能用于修改基础集。
     
    最初,枚举数定位在集合中第一个元素前。Reset 方法还会将枚举数返回到此位置。在此位置,调用 Current 属性会引发异常。因此,在读取 Current 的值之前,必须调用MoveNext 方法将枚举数提前到集合的第一个元素。在调用 MoveNext 或 Reset 之前,Current 返回同一对象。MoveNext 将 Current 设置为下一个元素。
    
    如果 MoveNext 越过集合的末尾,则枚举数将被放置在此集合中最后一个元素的后面,而且 MoveNext 返回 false。当枚举数位于此位置时,对 MoveNext 的后续调用也返回 false。如果最后一次调用 MoveNext 返回 false,则调用 Current 会引发异常。若要再次将 Current 设置为集合的第一个元素,可以调用 Reset,然后再调用MoveNext。
    
     只要集合保持不变,枚举数就保持有效。如果对集合进行了更改(如添加、修改或删除元素),则枚举数将失效且不可恢复,并且下一次对 MoveNext 或 Reset 的调用将引发InvalidOperationException。如果在 MoveNext 和 Current 之间修改集合,那么即使枚举数已经无效,Current 也将返回它所设置成的元素。
     
     枚举数没有对集合的独占访问权;因此,枚举通过集合在本质上不是一个线程安全的过程。即使一个集合已进行同步,其他线程仍可以修改该集合,这将导致枚举数引发异常。若要在枚举过程中保证线程安全,可以在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常。
 */

样例:

using System;
using System.Collections;
//person类
public class Person
{    public Person(string fName, string lName)
    {        
        this.firstName = fName;
        this.lastName = lName;
    }    
    public string firstName;
    public string lastName;
}

//People类,实现IEnumerable
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];
        }
    }    
    public IEnumerator GetEnumerator()
    { 
           return new PeopleEnum(_people);
    }
}

//实现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;
    }
     public object Current
    {        
        get
        {            
            try
            { 
                           return _people[position];
            }catch (IndexOutOfRangeException)
            {
                            throw new InvalidOperationException();
            }
        }
    }
}

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