C# yield关键字的作用 - 实现迭代器与状态机的简便方法

星降
发布: 2025-12-13 20:16:03
原创
385人浏览过
yield关键字用于声明迭代器方法,使方法能逐个提供序列元素并自动管理状态;返回类型须为IEnumerable等,编译器自动生成状态机,支持延迟计算与内存优化。

c# yield关键字的作用 - 实现迭代器与状态机的简便方法

yield 关键字在 C# 中不是用来“返回值”或“跳出方法”的,而是专门用于声明迭代器方法(iterator method)——它让方法能逐个提供序列元素,同时自动帮你管理状态,不用手动写复杂的迭代器类。

让方法变成可迭代的序列生成器

普通方法只能一次性返回一个结果,而用 yield return 的方法,每次调用 MoveNext()(比如在 foreach 中)时,会从上次暂停的位置继续执行,直到遇到下一个 yield return 或方法结束。这样你就能用很简洁的代码写出“边算边给”的逻辑。

  • 方法返回类型必须是 IEnumerable<t></t>IEnumerator<t></t> 或其非泛型对应类型
  • 方法体内不能有 return value;(但可以有 return; 表示结束迭代)
  • 不能在匿名方法、lambda 表达式或 async 方法中使用 yield(C# 7.0+ 支持 async 迭代器,但需用 IAsyncEnumerable<t></t>yield return 配合 await

编译器自动生成状态机,你不用操心细节

你写的含 yield 的方法,编译器会在后台生成一个私有嵌套类(状态机),实现 IEnumerator<t></t> 接口,并维护当前执行位置、局部变量等状态。你完全不用手动实现 CurrentMoveNext()Dispose() 等成员。

  • 所有局部变量会被“提升”为状态机类的字段,保证跨多次 MoveNext() 调用时值不丢失
  • 每个 yield return 对应一个状态编号,编译器用 switch 控制流程跳转
  • 调试时能看到自动生成的 <methodname>d__N</methodname> 类,但日常开发无需关注

常见实用场景:延迟计算 + 节省内存

适合处理大数据流、无限序列、IO 边读边处理等场景,避免一次性加载全部数据到内存。

Lateral App
Lateral App

整理归类论文

Lateral App 85
查看详情 Lateral App
  • 遍历文件行:foreach (var line in ReadLines("log.txt")) { ... },每行只读一次、不缓存全文
  • 生成斐波那契数列:yield return a; int temp = a; a = b; b = temp + b;,按需计算下一项
  • 过滤并转换集合:foreach (var x in source) if (x > 0) yield return x * 2;,链式处理无中间数组

注意:yield break 提前终止迭代

yield break 不是退出方法,而是告诉迭代器“这里没更多元素了”,后续调用 MoveNext() 将返回 false。常用于条件提前结束,比如空集合检查或达到阈值。

  • if (items == null) yield break;
  • for (int i = 0; i

基本上就这些。用好 yield,写迭代逻辑更轻量、更直观,也更符合 .NET 的惯用风格。

以上就是C# yield关键字的作用 - 实现迭代器与状态机的简便方法的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号