• MoveNext 将当前元素向前移动到下一个位置,如果集合没有更多元素,那么它会返回false。
  • Current 返回当前位置元素。在取得第一个元素之前 必须先调用 MoveNext ,即使空集合也支持该操作。
  • Reset 作用就是当前位置移回起点,并允许再一次枚举集合。此方法一般并不建议使用,因为完全可以重新实例化一个枚举器。
  • 通常,集合本身并不实现枚举器,而是通过 IEnumerable 接口提供枚举器:

    public interface IEnumerable: 
        IEnumerator GetEnumerator();
    

      通过GetEnumerator返回枚举器,可以灵活地将迭代逻辑转移到另一个类上。此外,多个消费者可以同时枚举同一个集合而不互相影响。IEnumerable可以看作IEnumerator的提供者,它是所有集合类需要实现的最基础接口。

      下面示例了基本用法:

    string s = "Hello";
    IEnumerator rator = s.GetEnumerator();
    while (rator.MoveNext())
        char c = (char)rator.Current;
        Console.Write(c + ".");
    

      然而,我们很少采用这种方式直接调用枚举器的方法,因为C#提供了更快捷的语法:foreach语句。

    foreach (char c in s)
        Console.Write(c + ".");
    

    IEnumerable<T> 和 IEnumerator<T>

      IEnumerable 和 IEnumerator 总是和它们的泛型版本同时实现:

    public interface IEnumerator<T> : IEnumerator, IDisposable
        T Current { get; }
    public interface IEnumerable<T> : IEnumerable
        IEnumerator<T> GetEnumerator();
    

      这些接口通过定义一个类型化的CurrentGetEnumerator强化了静态类型安全性,避免了值类型元素装箱的额外开销,更加方便了。

      集合类的标准做法是公开提供IEnumerable<T>接口,并通过显式接口实现,而“隐藏”非泛型的IEnumerable接口。如果直接调用GetEnumerator(),则返回类型安全的泛型IEnumerator<T>。但是有时候这个规则也会由于向后兼容性而破坏,比如数组就必须返回非泛型的以避免破坏之前C#版本代码。

      IEnumerator<T>也同时继承了IDisposable,这样枚举器就可以在枚举结束后确保释放这些资源。

    本文来自博客园,作者:一纸年华,转载请注明原文链接:https://www.cnblogs.com/nullcodeworld/p/16424911.html