为什么在这个例子中(来自msdn),在GetEnumerator方法中,新的PeopleEnum返回IEnumerator?

时间:2010-04-14 06:10:02

标签: c# ienumerable ienumerator

为什么在MSDN的此示例中,在GetEnumerator方法中,PeopleEnum会返回IEnumerator

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

    public string firstName;
    public string lastName;
}

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];
        }
    }
   //why??? 
   IEnumerator IEnumerable.GetEnumerator()
   {
       return (IEnumerator) GetEnumerator();
   }

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

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();
        }
    }
}

更新 顺便说一句,如果Array数据类型实现ICloneable接口,为什么msdn通过编写for循环将pArray复制到_people?

2 个答案:

答案 0 :(得分:3)

需要返回完全 IEnumerator才能正确实现IEnumerable接口。它是使用“显式接口实现”执行此操作的,因此在公共 API上,您看到PeopleEnum,但IEnumerable仍然很满意

但实际上你很少很少在C#2.0或更高版本中以这种方式写一个枚举器;你会使用迭代器块(yield return)。见C# in Depth第6章(免费章节!)。

有关信息,PeopleEnum在中存在的原因是这看起来像.NET 1.1示例,这是创建类型化枚举器的唯一方法。在.NET 2.0及更高版本中,IEnumerable<T> / IEnumerator<T>有一个类型(通过泛型).Current

在.NET 2.0 / C#2.0(或更高版本)中,我只想:

public class People : IEnumerable<Person> {
    /* snip */
    public IEnumerator<Person> GetEnumerator() {
        return ((IEnumerable<Person>)_people).GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator() { return _people.GetEnumerator();}
}

答案 1 :(得分:2)

实现IEnumerable的类型需要一个名为GetEnumerator的方法来返回一个IEnumerator。在该示例中(从C#2.0开始已经过时),有一个实现IEnumerator的枚举器类PeopleEnum。它是C#foreach语句在内部使用的内容。

更新的示例看起来更像是以下内容。请注意,现在C#支持迭代器不再需要PeopleEnum类。有效地,编译器会为您完成所有繁重的工作。

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];
        }
    }

   IEnumerator IEnumerable.GetEnumerator()
   {
       for (int i=0; i < _people.Length; i++) {
           yield return _people[i];
       }
   }
}