首页 > 其他分享 >yield 语句 - 提供下一个元素

yield 语句 - 提供下一个元素

时间:2024-10-16 15:00:44浏览次数:7  
标签:语句 Console 迭代 int 元素 yield C# return

yield 语句 - 提供下一个元素

本文内容

  1. 迭代器的执行
  2. C# 语言规范
  3. 另请参阅

迭代器中使用 yield 语句提供下一个值或表示迭代结束。 yield 语句有以下两种形式:

  • yield return:在迭代中提供下一个值,如以下示例所示:

    C#
    foreach (int i in ProduceEvenNumbers(9))
    {
        Console.Write(i);
        Console.Write(" ");
    }
    // Output: 0 2 4 6 8
    
    IEnumerable<int> ProduceEvenNumbers(int upto)
    {
        for (int i = 0; i <= upto; i += 2)
        {
            yield return i;
        }
    }
    
  • yield break:显式示迭代结束,如以下示例所示:

    C#
    Console.WriteLine(string.Join(" ", TakeWhilePositive(new int[] {2, 3, 4, 5, -1, 3, 4})));
    // Output: 2 3 4 5
    
    Console.WriteLine(string.Join(" ", TakeWhilePositive(new int[] {9, 8, 7})));
    // Output: 9 8 7
    
    IEnumerable<int> TakeWhilePositive(IEnumerable<int> numbers)
    {
        foreach (int n in numbers)
        {
            if (n > 0)
            {
                yield return n;
            }
            else
            {
                yield break;
            }
        }
    }
    

    当控件到达迭代器的末尾时,迭代也结束。

在前面的示例中,迭代器的返回类型为 IEnumerable<T>(在非泛型情况下,使用 IEnumerable 作为迭代器的返回类型)。 还可以使用 IAsyncEnumerable<T> 作为迭代器的返回类型。 这使得迭代器异步。 使用 await foreach 语句对迭代器的结果进行迭代,如以下示例所示:

C#
await foreach (int n in GenerateNumbersAsync(5))
{
    Console.Write(n);
    Console.Write(" ");
}
// Output: 0 2 4 6 8

async IAsyncEnumerable<int> GenerateNumbersAsync(int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return await ProduceNumberAsync(i);
    }
}

async Task<int> ProduceNumberAsync(int seed)
{
    await Task.Delay(1000);
    return 2 * seed;
}

迭代器的返回类型可以是 IEnumerator<T> 或 IEnumerator。 在以下方案中实现 GetEnumerator 方法时,请使用这些返回类型:

  • 设计实现 IEnumerable<T> 或 IEnumerable 接口的类型。

  • 添加实例或扩展 GetEnumerator 方法来使用 foreach 语句对类型的实例启用迭代,如以下示例所示:

    C#
    public static void Example()
    {
        var point = new Point(1, 2, 3);
        foreach (int coordinate in point)
        {
            Console.Write(coordinate);
            Console.Write(" ");
        }
        // Output: 1 2 3
    }
    
    public readonly record struct Point(int X, int Y, int Z)
    {
        public IEnumerator<int> GetEnumerator()
        {
            yield return X;
            yield return Y;
            yield return Z;
        }
    }
    

不能在下列情况中使用 yield 语句:

  • 带有 inref 或 out 参数的方法
  • Lambda 表达式匿名方法
  • 不安全块。 在 C# 13 之前,yield 在具有 unsafe 块的任何方法中都无效。 从 C# 13 开始,可以在包含 unsafe 块的方法中使用 yield,但不能在 unsafe 块中使用。
  • yield return 和 yield break 不能在 trycatch 和 finally 块中使用。

迭代器的执行

迭代器的调用不会立即执行,如以下示例所示:

C#
var numbers = ProduceEvenNumbers(5);
Console.WriteLine("Caller: about to iterate.");
foreach (int i in numbers)
{
    Console.WriteLine($"Caller: {i}");
}

IEnumerable<int> ProduceEvenNumbers(int upto)
{
    Console.WriteLine("Iterator: start.");
    for (int i = 0; i <= upto; i += 2)
    {
        Console.WriteLine($"Iterator: about to yield {i}");
        yield return i;
        Console.WriteLine($"Iterator: yielded {i}");
    }
    Console.WriteLine("Iterator: end.");
}
// Output:
// Caller: about to iterate.
// Iterator: start.
// Iterator: about to yield 0
// Caller: 0
// Iterator: yielded 0
// Iterator: about to yield 2
// Caller: 2
// Iterator: yielded 2
// Iterator: about to yield 4
// Caller: 4
// Iterator: yielded 4
// Iterator: end.

如前面的示例所示,当开始对迭代器的结果进行迭代时,迭代器会一直执行,直到到达第一个 yield return 语句为止。 然后,迭代器的执行会暂停,调用方会获得第一个迭代值并处理该值。 在后续的每次迭代中,迭代器的执行都会在导致上一次挂起的 yield return 语句之后恢复,并继续执行,直到到达下一个 yield return 语句为止。 当控件到达迭代器或 yield break 语句的末尾时,迭代完成。

C# 语言规范

有关详细信息,请参阅 C# 语言规范中的 yield 语句部分。

另请参阅

标签:语句,Console,迭代,int,元素,yield,C#,return
From: https://www.cnblogs.com/sexintercourse/p/18469945

相关文章

  • 代码随想录算法训练营第一天|704二分查找、27移除元素、977有序数组的平方
    代码随想录算法训练营第一天|704二分查找、27移除元素、977有序数组的平方1Leetcode704二分查找题目链接:[704.二分查找](704.二分查找-力扣(LeetCode))文章链接:[代码随想录](代码随想录(programmercarl.com))视频链接:[手把手带你撕出正确的二分法|二分查找法|二分搜......
  • 【c#】我们为什么要用 yield return
    【c#】我们为什么要用yieldreturn明尼苏达的微笑嗯嗯,你说的都对​关注他 43人赞同了该文章声明:本文部分内容来自《moreeffectivec#》,特此声明c#里面的yieldreturn没什么高大上的,就是一个一个的return。但是我们不能小看这种用法,他能给编......
  • 第六章 元素应用CSS
    6.1使用CSS设置字体样式6.1.1.字体类型CSS提供font-family属性来控制文本的字体类型。格式如下:font-family:字体名称;参数:字体名称按优先顺序排列,以逗号隔开。如果字体名称包含空格,则应用引号括起。说明:用font-family属性可控制显示字体。不同的操作系统,其字体名是......
  • 3194. 最小元素和最大元素的最小平均值
    你有一个初始为空的浮点数数组averages。另给你一个包含n个整数的数组nums,其中n为偶数。你需要重复以下步骤n/2次:从nums中移除最小的元素minElement和最大的元素maxElement。将(minElement+maxElement)/2加入到averages中。返回averages中的最......
  • goto语句的风险
    在编程中,goto语句会使程序控制流跳转到指定的标签位置。尽管它在某些情况下可以简化代码(例如在错误处理或异常情况下快速退出多个嵌套的循环),但通常建议慎用甚至避免使用goto语句。主要原因如下:1. 破坏代码的结构化goto语句允许程序跳转到代码中的任意位置,从而打破了程序的结构......
  • CSS伪元素详解
    CSS伪元素详解一、引言在CSS中,伪元素是一个非常强大的工具,它允许我们为元素的特定部分添加样式,而无需修改HTML结构。这不仅提高了样式的灵活性,还有助于保持代码的整洁和可维护性。本文将深入探讨CSS伪元素的使用方法和一些实用技巧。二、伪元素的基本概念1、伪元素的定......
  • Java 列表元素自定义排序
    在Java开发过程中,有时会遇到需要对列表中元素进行自定义的排序。这样的排序往往不能由元素本身的特性(比如字符串长度、首字母顺序)判断,需要自己指定顺序。比如对汉字的数字进行排序,他们的字符串长度都为1,首字母顺序也不能得到预期的结果,因此需要自定义排序。以下是示例代码:p......
  • C#中判断的应用说明二(switch语句)
    一.判断的定义说明判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。下面是大多数编程语言中典型的判断结构的一般形式:二.判断语句C#提供了以下类型的判断语句,查看每个语句的细节。语句描述switch语......
  • 如何避免日志中打印SQL语句:完整解决方案
    个人名片......
  • 生成器yield
    在Python中,yield是一个关键字,用于定义生成器函数。生成器函数是一种特殊类型的函数,它返回一个生成器对象,可以用于迭代。与普通函数不同,生成器函数不一次性返回结果,而是每次生成一个值,并在需要时继续执行。生成器函数:使用yield关键字的函数。调用生成器函数不会立即执行......