🔁
一句话理解:迭代器提供顺序访问集合元素的统一方式,同时隐藏集合的内部表示和遍历细节。

C# 已经内置了迭代器协议

IEnumerable<T> 表示可遍历集合,IEnumerator<T> 保存一次遍历的当前位置。大多数 Unity 代码无需手写 GoF 迭代器类,使用 yield return 就能表达自定义遍历。

示例:只遍历可用物品

调用方只需:
以后即使替换内部存储,遍历代码也不必改变。

何时需要自定义迭代器

  • 树的深度优先或广度优先遍历
  • 跳过无效、隐藏或未解锁元素
  • 分页读取大型数据集
  • 同一集合提供多种遍历顺序
  • 不暴露内部集合,避免调用方随意修改

Unity 注意事项

协程也使用 IEnumerator,但它表达的是跨帧执行流程,不是集合遍历,两者不要混淆。热路径中要用 Profiler 检查装箱、闭包和 LINQ 分配;不要仅凭“用了迭代器”推断是否产生 GC。
遍历期间修改集合通常会导致异常或不一致,应明确使用快照、延迟修改队列,或禁止并发修改。

小结

迭代器把“如何遍历”从“如何使用元素”中分离。C# 已提供成熟协议,优先利用语言能力,只有特殊顺序或性能约束出现时才自定义实现。