请解释在 C# 中,yield return 和迭代器方法的底层实现机制是怎样的?
考察说明
考察对 C# 迭代器语法糖底层编译原理和状态机机制的理解。
回答思路
- 【回答框架 1】编译器在遇到包含 yield return 的方法时,会将其转换为一个实现 IEnumerable 或 IEnumerator 的私有嵌套类,原始方法体被拆分并移动到该类的 MoveNext 方法中。
- 【回答框架 2】该状态机类维护状态字段和局部变量字段,每次 MoveNext 调用执行一段代码直到下一个 yield return,记录当前位置,返回 true;没有更多 yield 时返回 false。
- 【回答框架 3】yield break 对应状态机设置完成标志,使 MoveNext 返回 false 并释放资源。
- 【回答框架 4】使用 foreach 时,编译器生成的代码调用 GetEnumerator 并循环调用 MoveNext,通过 Current 属性获取当前值,迭代变量在每次迭代中更新。
- 【关键点 1】yield return 是语法糖,底层生成状态机类。
- 【关键点 2】状态机保存执行位置和局部变量,支持延迟执行。
- 【关键点 3】迭代器方法直到 MoveNext 时才真正执行代码。
- 【易错点 1】在迭代器块中使用 ref 或 out 参数不被允许。
- 【易错点 2】迭代器方法中的 try-finally 在 Dispose 时会执行,但带 yield return 的 try-catch 有限制,不能 catch 迭代期间的异常。