2

为什么在这个来自 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 ?

4

2 回答 2

3

它需要准确 IEnumerator返回才能正确实现IEnumerable接口。它使用“显式接口实现”来执行此操作,因此在您看到的公共PeopleEnumAPI 上,但IEnumerable仍然很高兴

但实际上,您很少会在 C# 2.0 或更高版本中以这种方式编写枚举器;您将使用迭代器块 ( yield return)。请参阅深度第 6 章中的 C#(免费章节!)。

对于信息,这里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();}
}
于 2010-04-14T06:14:13.887 回答
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];
       }
   }
}
于 2010-04-14T06:16:19.687 回答