欢迎您访问新疆栾骏商贸有限公司,公司主营电子五金轴承产品批发业务!
全国咨询热线: 400-8878-609

新闻资讯

技术学院

C#如何使用yield return关键字 C#迭代器实现方法

作者:星降2025-12-19 00:00:00
yield return 是 C# 中实现延迟执行、节省内存的自定义迭代器的核心机制,支持按需生成序列、树遍历等场景,但受限于方法签名与语法约束。

在C#中,yield return 是实现自定义迭代器最简洁、高效的方式,它让方法能按需生成序列,无需一次性构造整个集合,节省内存且支持延迟执行。

yield return 的基本用法

yield return 修饰的方法必须返回 IEnumerableIEnumerator,且不能有 return 语句(除 return; 外),也不能有 ref/out 参数或 try-catch 块(除非 catch 内无 yield,且 finally 中不能有 yield)。

每次调用迭代器的 MoveNext(),代码从上一次 yield return 暂停处继续执行,直到下一个 yield return 或方法结束。

  • 每个 yield return 返回一个元素,控制权交还给调用方
  • yield break 可提前终止迭代,等效于自然退出
  • 编译器会将含 yield 的方法自动转换为状态机类(编译后可见)

实现简单数值序列的迭代器

例如生成 1 到 n 的平方数:

public static IEnumerable Squares(int n)
{
    for (int i = 1; i <= n; i++)
    {
        yield return i * i;
    }
}

调用时可直接用于 foreach 或 LINQ:

foreach (int sq in Squares(5))
    Console.WriteLine(sq); // 输出 1, 4, 9, 16, 25

注意:该方法不会立即执行循环,只有在第一次枚举时才开始计算——这就是延迟执行

用 yield return 实现树的中序遍历

递归 + yield 是处理嵌套结构的常用模式。假设有一个二叉树节点类:

public class TreeNode
{
    public int Value { get; set; }
    public TreeNode Left { get; set; }
    public TreeNode Right { get; set; }
}

中序遍历(左-根-右)可这样写:

public static IEnumerable InOrder(TreeNode node)
{
    if (node == null) yield break;
foreach (var v in InOrder(node.Left))  yield return v;
yield return node.Value;
foreach (var v in InOrder(node.Right)) yield return v;

}

这种方式逻辑清晰,避免手动维护栈,也保持了延迟求值特性——遍历到哪才计算到哪。

注意事项与常见误区

yield return 看似简单,但容易踩坑:

  • 不能在匿名方法、lambda 表达式或异步方法(async)中使用 yield
  • 局部变量在多次迭代中会被保留(闭包行为),注意引用生命周期
  • 每次调用迭代器方法都会创建新的枚举器,互不影响;但若方法内捕获了外部可变状态,需谨慎线程安全
  • 调试时无法在 yield return 行设断点(VS 中可能跳过),建议用日志或拆分逻辑辅助排查

基本上就这些。掌握 yield return 后,写数据流处理、配置解析、文件逐行读取等场景会变得非常自然和轻量。