翼度科技»论坛 编程开发 .net 查看内容

解读 --- yield 关键字

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
引言

yield关键字是 C# 中的一种语言特性,用于在枚举器中简化迭代器的实现。它使得开发人员可以通过定义自己的迭代器来简化代码,而不必手动实现 IEnumerable 和 IEnumerator 接口。
使用 yield 关键字,可以将迭代器中的值一次一个地返回,而不必使用一个集合对象存储所有的值。当执行到yield return语句时,代码将会暂停执行,将返回值传递给迭代器的调用者,并将迭代器的状态保存下来。当下一次调用MoveNext方法时,代码将从之前的暂停点继续执行,直到遇到下一个yield return语句或者迭代器结束。
接下来探索一下 yield 的三种玩法:
初级

例如通过 yield 创建出一个 IEnumerable 以供 foreach 遍历,代码如下:
  1. internal class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         foreach (int i in EvenSequence(5, 18))
  6.         {
  7.             Console.Write(i + " ");
  8.         }
  9.         Console.ReadKey();
  10.     }
  11.    
  12.     static IEnumerable<int> EvenSequence(int start, int end)
  13.     {
  14.         for (int i = start; i <= end; i++)
  15.         {
  16.             if (i % 2 == 0)
  17.             {
  18.                 yield return i;
  19.             }
  20.         }
  21.     }
  22. }
复制代码
开始舀水,代码如下:
  1. public class Program
  2. {
  3.     public static void Main(string[] args)
  4.     {
  5.         AsynchronousIterate();
  6.         Console.ReadLine();
  7.     }
  8.     public static async void AsynchronousIterate()
  9.     {
  10.         await foreach (var number in GenerateNumbersAsync())
  11.         {
  12.             Console.WriteLine(number);
  13.         }
  14.     }
  15.     public static async IAsyncEnumerable<int> GenerateNumbersAsync()
  16.     {
  17.         for (int i = 0; i < 10; i++)
  18.         {
  19.             await Task.Delay(1000);
  20.             yield return i;
  21.         }
  22.     }
  23. }
复制代码
最终会每次随机舀水,花费随机时间,水全部舀完。
输出:
  1. static Random Random = new Random();
  2. /// <summary>
  3. /// 假设水缸能盛水90~100
  4. /// </summary>
  5. public static int GetOneWaterTankCapacity()
  6. {
  7.     return Random.Next(150, 200);
  8. }
  9. /// <summary>
  10. /// 假设水瓢一次只能舀水2~5
  11. /// </summary>
  12. public static int GetOneWaterLadleCapacity()
  13. {
  14.     return Random.Next(2, 5);
  15. }
  16. /// <summary>
  17. /// 模拟舀水所消耗的时间(0.5s~2S)
  18. /// </summary>
  19. /// <returns></returns>
  20. public static async Task<int> ScoopingWater()
  21. {
  22.     await Task.Delay(Random.Next(500, 2000));
  23.     return GetOneWaterLadleCapacity();
  24. }
复制代码
通过上文例子,可以更深入理解 yield 创建的异步生成器。
总结


  • 使用 yield 关键字可以将一个方法转换为一个返回可枚举对象或迭代器的方法,而不必手动实现 IEnumerable 和 IEnumerator 接口
  • 使用 yield 来创建异步生成器,在某些场景下可以实现更高效、可靠的异步编程。

来源:https://www.cnblogs.com/pandefu/archive/2023/07/17/17536297.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具