迭代器与枚举器
枚举器 枚举器的作用 如果想遍历一个集合(数组、列表等),通常会用到 foreach。其背后依赖的就是枚举器。 枚举器本质上是一种状态机:提供统一的遍历方式,同时不暴露集合的内部结构。 先看一个简单示例: public class MyIterator:IEnumerable { public IEnumerator GetEnumerator() { return new MyEnumerator(); } private class MyEnumerator : IEnumerator { private int _index = -1; public object Current { get { switch (_index) { case 0: return 1; case 1: return 2; case 2: return 3; default: throw new InvalidOperationException(); } } } public bool MoveNext() { _index++; return _index < 3; } public void Reset() { _index = -1; } } } var iterator1 = new MyIterator(); foreach (var item in iterator1) { Console.WriteLine(item); } // 输出: // 1 // 2 // 3 在上面的代码中,我们定义了一个 MyIterator 类,它实现了 IEnumerable 接口。GetEnumerator 方法返回一个实现了 IEnumerator 接口的枚举器 MyEnumerator。MyEnumerator 类中包含了三个核心成员: Current 属性:返回当前枚举器指向的元素。 MoveNext 方法:将枚举器推进到下一个元素。 Reset 方法:将枚举器重置到初始位置。 当我们使用 foreach 循环遍历 MyIterator 实例时,实际上是通过调用 GetEnumerator 方法获取枚举器,然后不断调用 MoveNext 方法来推进枚举器,并通过 Current 属性获取当前元素,直到 MoveNext 返回 false,表示枚举结束。 需要了解的是遍历并不是在集合对象上直接进行的,而是通过枚举器在不同状态下返回值的方式来推进的。 基于状态机编译可以实现延迟执行,只有在需要时才取下一条数据,而不是一次性把所有内容读进内存。在数据量很大的场景,能显著降低内存压力并且提高读取速度。 ...