C#使用yield关键字提升迭代性能与效率
        【摘要】 前言yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,减少了内存占用,并允许在迭代时执行复杂逻辑。传统迭代和yield迭代方式对比咱们来看看传统迭代方式和yield关键字迭代方式对比,是否如传说中的代码实现起来更简洁和高效:        /// <summary>        /// 传统迭代方式和yield关键字迭代方式对比        /// </...
    
    
    
    前言
yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,减少了内存占用,并允许在迭代时执行复杂逻辑。
传统迭代和yield迭代方式对比
咱们来看看传统迭代方式和yield关键字迭代方式对比,是否如传说中的代码实现起来更简洁和高效:
        /// <summary>
        /// 传统迭代方式和yield关键字迭代方式对比
        /// </summary>
        public static void IteratorComparisonRun()
        {
            Console.WriteLine("迭代器方法使用yield关键字:");
            foreach (var number in GetNumbersWithYield())
            {
                Console.WriteLine(number);
            }
            Console.WriteLine("传统迭代方法返回一个List<int>");
            var numbers = GetNumbersWithoutYield();
            foreach (var number in numbers)
            {
                Console.WriteLine(number);
            }
        }
        /// <summary>
        /// 迭代器方法使用yield关键字
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<int> GetNumbersWithYield()
        {
            for (int i = 0; i < 6; i++)
            {
                yield return i;
            }
        }
        /// <summary>
        /// 传统迭代方法返回一个List<int>
        /// </summary>
        /// <returns></returns>
        public static List<int> GetNumbersWithoutYield()
        {
            var numbers = new List<int>();
            for (int i = 0; i < 6; i++)
            {
                numbers.Add(i);
            }
            return numbers;
        }
输出结果:

yield延迟加载按需获取数据
yield关键字可以通过延迟执行的方式,仅在实际需要时生成数据,从而提高了性能和效率。
        /// <summary>
        /// yield关键字延迟加载按需获取数据
        /// </summary>
        public static void LazyLoadingRun()
        {
            Console.WriteLine("yield延迟加载按需获取数据 开始...");
            foreach (var number in GetEvenNumbers(11))
            {
                Console.WriteLine($"返回值 === {number} ===");
                Thread.Sleep(500);
            }
            Console.WriteLine("yield延迟加载按需获取数据 结束...");
        }
        /// <summary>
        /// 使用yield返回偶数的迭代器方法
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<int> GetEvenNumbers(int number)
        {
            for (int i = 1; i < number; i++)
            {
                Console.WriteLine($"Yielding {i}");
                if (i % 2 == 0)
                {
                    yield return i; //只在需要时生成偶数
                }
            }
        }
输出结果:

yield break显式示迭代结束
yield break:显式示迭代结束,如以下示例所示:
        public static void YieldBreakRun()
        {
            Console.WriteLine(string.Join(" ", TakeWhilePositive(new int[] { 1, 3, 4, 5, -1, 3, 4 })));
            //输出:1 3 4 5
            Console.WriteLine(string.Join(" ", TakeWhilePositive(new int[] { 9, 8, 7, 6, 5, -5, 88, 100 })));
            //输出:9 8 7 6 5
        }
        public static IEnumerable<int> TakeWhilePositive(IEnumerable<int> numbers)
        {
            foreach (int n in numbers)
            {
                if (n > 0)
                {
                    yield return n;
                }
                else
                {
                    yield break;
                }
            }
        }
什么情况不能使用yield关键字
- 
带有 in、ref 或 out 参数的方法。 
- 
Lambda 表达式和匿名方法。 
- 
在 C# 13 之前,yield 在具有 unsafe 块的任何方法中都无效。从 C# 13 开始,可以在包含 unsafe 块的方法中使用 yield,但不能在 unsafe 块中使用。 
- 
不能在catch和finally块中使用yield return和yield break。 
- 
不能在具有catch块的try块中使用yield return和yield break。 
- 
可以在只有finally块的try块中使用yield return和yield break。 
完整示例代码

参考文章
- 
https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/statements/yield 
            【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
                cloudbbs@huaweicloud.com
                
            
        
        
        
        
        
        
        - 点赞
- 收藏
- 关注作者
 
             
           
评论(0)