一句话理解:迭代器提供顺序访问集合元素的统一方式,同时隐藏集合的内部表示和遍历细节。
C# 已经内置了迭代器协议
IEnumerable<T> 表示可遍历集合,IEnumerator<T> 保存一次遍历的当前位置。大多数 Unity 代码无需手写 GoF 迭代器类,使用 yield return 就能表达自定义遍历。示例:只遍历可用物品
调用方只需:
以后即使替换内部存储,遍历代码也不必改变。
何时需要自定义迭代器
- 树的深度优先或广度优先遍历
- 跳过无效、隐藏或未解锁元素
- 分页读取大型数据集
- 同一集合提供多种遍历顺序
- 不暴露内部集合,避免调用方随意修改
Unity 注意事项
协程也使用
IEnumerator,但它表达的是跨帧执行流程,不是集合遍历,两者不要混淆。热路径中要用 Profiler 检查装箱、闭包和 LINQ 分配;不要仅凭“用了迭代器”推断是否产生 GC。遍历期间修改集合通常会导致异常或不一致,应明确使用快照、延迟修改队列,或禁止并发修改。
小结
迭代器把“如何遍历”从“如何使用元素”中分离。C# 已提供成熟协议,优先利用语言能力,只有特殊顺序或性能约束出现时才自定义实现。