C# yield 关键字

文章目录

  • 前言
  • 一、yield 关键字的语法形式及使用场景
    • (一)yield return
    • (二)yield break
  • 二、yield 关键字的工作原理
  • 三、yield 关键字的优势与应用场景
    • (一)优势
    • (二)应用场景


前言

  在 C# 中,yield 关键字是一个非常独特且强大的语言特性,它主要用于迭代器块(Iterator Block)中,能够让开发者以一种简洁高效的方式实现自定义的可迭代类型,轻松地生成并返回一个序列的值,而无需像传统方式那样创建一个完整的集合对象来存储所有要返回的数据。简单来说,yield 关键字帮助我们实现了一种 “按需生成” 数据的机制,特别适用于处理大数据量或者无限序列的情况,避免了一次性占用大量内存空间。
  例如,想象要生成一个包含所有自然数的序列,如果不使用 yield 关键字,可能需要先创建一个非常大的数组或者列表来存储这些数,这显然会消耗大量内存且效率低下。而借助 yield 关键字,就可以在需要的时候逐个生成这些自然数,不会造成不必要的内存开销。
在这里插入图片描述

一、yield 关键字的语法形式及使用场景

(一)yield return

  yield return 语句是 yield 关键字最常见的用法,它用于从迭代器块中返回一个值,并且会 “记住” 当前的执行位置,下次调用迭代器继续执行时,会从这个位置接着往下执行,继续生成下一个值,以此类推,直到迭代结束。
  以下是一个简单的示例,定义了一个方法来生成斐波那契数列(这里只生成有限项):

using System;
using System.Collections.Generic;public static IEnumerable<int> FibonacciSequence(int count)
{int a = 0, b = 1;for (int i = 0; i < count; i++){yield return a;int temp = a;a = b;b = temp + b;}
}

  在上述代码中,FibonacciSequence 方法返回一个实现了 IEnumerable 接口的可迭代序列,通过 yield return 语句,每次循环时返回斐波那契数列中的一项。例如,我们可以这样调用并遍历这个序列:

foreach (int num in FibonacciSequence(10))
{Console.Write(num + " ");
}

  输出结果将会是斐波那契数列的前 10 项:0 1 1 2 3 5 8 13 20 34。在这个过程中,每次 foreach 循环迭代时,就会触发 yield return 执行,生成下一个数列的值,并不会一次性把整个斐波那契数列都计算并存储好再返回。

(二)yield break

  yield break 语句用于终止迭代器的执行,提前结束整个迭代过程。通常在满足某些特定条件,不需要再继续生成后续数据时使用。
  例如,修改上面的斐波那契数列生成方法,假设当生成的数大于 100 时就停止生成,代码可以修改为如下:

using System;
using System.Collections.Generic;public static IEnumerable<int> FibonacciSequence(int count)
{int a = 0, b = 1;for (int i = 0; i < count; i++){if (a > 100){yield break;}yield return a;int temp = a;a = b;b = temp + b;}
}

  在这个示例中,一旦生成的斐波那契数 a 大于 100,就会执行 yield break,迭代器停止工作,后续的元素就不会再被生成和返回了。

二、yield 关键字的工作原理

  当使用 yield 关键字的迭代器方法被调用时(比如在 foreach 循环中调用),编译器会自动生成一个状态机(State Machine)来管理迭代的过程。这个状态机负责跟踪迭代器的当前执行位置、局部变量的值等信息,每次遇到 yield return 时,它会保存当前的状态,返回相应的值给调用者,等到下一次调用继续迭代时,又能恢复到之前保存的状态,接着往下执行,继续生成下一个值。
  从内存管理角度来看,由于数据是按需生成的,在某个时刻只有当前正在生成和返回的值会占用内存,而不是一次性将整个序列的数据都加载到内存中,这对于处理大量数据或者无限序列的情况非常有优势,大大节省了内存资源,同时也提升了程序的性能和响应速度。

三、yield 关键字的优势与应用场景

(一)优势

内存高效: 避免了提前创建和存储大量的数据,只在需要的时候生成并返回值,有效减少了内存占用,特别是对于大数据集或者无限长的序列,这种优势更为明显。
代码简洁: 能够以简洁的代码实现复杂的可迭代逻辑,相较于传统的通过创建集合对象、手动管理索引等方式来生成序列数据,使用 yield 关键字的代码更加清晰、易读和易于维护。
灵活性高: 可以方便地根据不同的条件动态地生成数据序列,比如根据用户输入、运行时的配置等因素实时调整生成的数据内容,而不需要对整个数据生成逻辑进行大规模重构。

(二)应用场景

处理大数据集合: 比如从数据库中查询大量的数据记录,不想一次性将所有记录都加载到内存中,可以使用 yield 关键字实现一个迭代器,每次从数据库中读取一条记录并返回,这样可以在内存有限的情况下高效地处理大量数据。
生成无限序列: 像生成自然数序列、质数序列等无限长的序列时,使用 yield 关键字能够让程序可以持续生成后续的值,而不会因为内存耗尽而崩溃,同时调用者可以根据自己的需要获取指定数量的元素,具有很高的灵活性。
遍历复杂的数据结构: 当需要遍历一些复杂的数据结构(如树形结构、图结构等),并按照特定顺序返回节点的值时,利用 yield 关键字可以轻松地实现深度优先遍历、广度优先遍历等不同的遍历逻辑,将遍历过程中节点的值逐个返回给调用者。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/61820.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT6学习第八天 QFrame 类

QT6学习第八天 QFrame 类族QLabel 标签部件按钮部件QLineEdit 行编辑器部件QAbstractSpinBoxQAbstractSlider 今天来学一学 QFrame 类。 QFrame 类族 QFrame 类是带有边框的部件的基类。它的子类包括常用的标签部件 QLabel、以及 QLCDNumber、QSplitter、QStackedWidget、QToo…

【2024 re:Invent现场session参加报告】打造生成式AI驱动的车间智能助手

前言 这次参加了 re:Invent 2024 的 Builders Session 「Building a generative AI–powered shop floor assistant」&#xff0c;在这里和大家分享一下内容&#xff01; Session 概要 Learn how to build a generative AI assistant to analyze data from industrial IoT se…

【C++】数组

1.概述 所谓数组&#xff0c;就是一个集合&#xff0c;该集合里面存放了相同类型的数据元素。 数组特点&#xff1a; &#xff08;1&#xff09;数组中的每个数据元素都是相同的数据类型。 &#xff08;2&#xff09;数组是有连续的内存空间组成的。 2、一维数组 2.1维数组定…

[VUE]框架网页开发02-如何打包Vue.js框架网页并在服务器中通过Tomcat启动

在现代Web开发中&#xff0c;Vue.js已经成为前端开发的热门选择之一。然而&#xff0c;将Vue.js项目打包并部署到生产环境可能会让一些开发者感到困惑。本文将详细介绍如何将Vue.js项目打包&#xff0c;并通过Tomcat服务器启动运行。 1. 准备工作 确保你的项目能够正常运行,项…

ESP32-S3模组上跑通ES8388(13)

接前一篇文章&#xff1a;ESP32-S3模组上跑通ES8388&#xff08;12&#xff09; 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析了es8388_init函数中的第6段代码&#xff0c;本回继续往下解析。为了便于理解和回顾&#xff0c;再次贴出es8388_init函数源码&#xff0c;在…

openEuler 22.03 使用cephadm安装部署ceph集群

目录 目的步骤规格步骤ceph部署前准备工作安装部署ceph集群ceph集群添加node与osdceph集群一些操作组件服务操作集群进程操作 目的 使用ceph官网的cephadm无法正常安装&#xff0c;会报错ERROR: Distro openeuler version 22.03 not supported 在openEuler上实现以cephadm安装部…

DevOps工程技术价值流:GitLab源码管理与提交流水线实践

在当今快速迭代的软件开发环境中&#xff0c;DevOps&#xff08;开发运维一体化&#xff09;已经成为提升软件交付效率和质量的关键。而GitLab&#xff0c;作为一个全面的开源DevOps平台&#xff0c;不仅提供了强大的版本控制功能&#xff0c;还集成了持续集成/持续交付(CI/CD)…

Spring 邮件发送

Spring 邮件发送 1. 主要内容&#xff08;了解&#xff09; 2. JavaMail 概述&#xff08;了解&#xff09; JavaMail&#xff0c;顾名思义&#xff0c;提供给开发者处理电⼦邮件相关的编程接⼝。JavaMail 是由 Sun 定义的⼀套收发电⼦邮件的 API&#xff0c;它可以⽅便地执⾏⼀…

VSCode如何关闭Vite项目本地自启动

某些情况下VSCode打开Vite项目不需要自动启动&#xff0c;那么如何关闭该功能 文件>首选项>设置 搜索vite 将Vite:Auto Start 勾选取消即可

一种多功能调试工具设计方案开源

一种多功能调试工具设计方案开源 设计初衷设计方案具体实现HUB芯片采用沁恒微CH339W。TF卡功能网口功能SPI功能IIC功能JTAG功能下行USB接口 安路FPGA烧录器功能Xilinx FPGA烧录器功能Jlink OB功能串口功能RS232串口RS485和RS422串口自适应接口 CAN功能烧录器功能 目前进度后续计…

Spark和MapReduce场景应用和区别

文章目录 Spark和MapReduce场景应用和区别一、引言二、MapReduce和Spark的应用场景1. MapReduce的应用场景2. Spark的应用场景 三、MapReduce和Spark的区别1. 内存使用和性能2. 编程模型和易用性3. 实时计算支持 四、使用示例1. MapReduce代码示例2. Spark代码示例 五、总结 Sp…

Python办公——openpyxl处理Excel每个sheet每行 修改为软雅黑9号剧中+边框线

目录 专栏导读背景1、库的介绍①&#xff1a;openpyxl 2、库的安装3、核心代码4、完整代码5、最快的方法(50万行44秒)——表头其余单元格都修改样式总结 专栏导读 &#x1f338; 欢迎来到Python办公自动化专栏—Python处理办公问题&#xff0c;解放您的双手 &#x1f3f3;️‍…

【C#】书籍信息的添加、修改、查询、删除

文章目录 一、简介二、程序功能2.1 Book类属性&#xff1a;方法&#xff1a; 2.2 Program 类 三、方法&#xff1a;四、用户界面流程&#xff1a;五、程序代码六、运行效果 一、简介 简单的C#控制台应用程序&#xff0c;用于管理书籍信息。这个程序将允许用户添加、编辑、查看…

01-树莓派基本配置-基础配置配置

树莓派基本配置 文章目录 树莓派基本配置前言硬件准备树莓派刷机串口方式登录树莓派接入网络ssh方式登录树莓派更换国内源xrdp界面登录树莓派远程文件传输FileZilla 前言 树莓派是一款功能强大且价格实惠的小型计算机&#xff0c;非常适合作为学习编程、物联网项目、家庭自动化…

无人机探测:光电侦测技术详解

一、基本原理 光电识别技术是无人机追踪设备的核心&#xff0c;其原理主要基于光电转换和信号处理技术。光电识别设备通过光学系统收集目标的光学信息&#xff0c;如可见光、红外光等&#xff0c;并将其转换为电信号。这些电信号随后被处理和分析&#xff0c;以实现对目标的识…

106.【C语言】数据结构之二叉树的三种递归遍历方式

目录 1.知识回顾 2.分析二叉树的三种遍历方式 1.总览 2.前序遍历 3.中序遍历 4.后序遍历 5.层序遍历 3.代码实现 1.准备工作 2.前序遍历函数PreOrder 测试结果 3.中序遍历函数InOrder 测试结果 4.后序遍历函数PostOrder 测试结果 4.底层分析 1.知识回顾 在99.…

go并发设计模式runner模式

go并发设计模式runner模式 真正运行的程序不可能是单线程运行的&#xff0c;go语言中最值得骄傲的就是CSP模型了&#xff0c;可以说go语言是CSP模型的实现。 假设现在有一个程序需要实现&#xff0c;这个程序有以下要求&#xff1a; 程序可以在分配的时间内完成工作&#xff0…

03-13、SpringCloud Alibaba第十三章,升级篇,服务降级、熔断和限流Sentinel

SpringCloud Alibaba第十三章&#xff0c;升级篇&#xff0c;服务降级、熔断和限流Sentinel 一、Sentinel概述 1、Sentinel是什么 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保…

【服务器问题】xshell 登录远程服务器卡住( 而 vscode 直接登录不上)

打开 xshell ssh 登录远程服务器&#xff1a;卡在下面这里&#xff0c;迟迟不继续 当 SSH 连接卡在 Connection established. 之后&#xff0c;但没有显示远程终端提示符时&#xff0c;这通常意味着连接已经成功建立&#xff0c;说明不是网络连接和服务器连接问题&#xff0c;…

图片预处理技术介绍4——降噪

图片预处理 大家好&#xff0c;我是阿赵。   这一篇将两种基础的降噪算法。   之前介绍过均值模糊和高斯模糊。如果从降噪的角度来说&#xff0c;模糊算法也算是降噪的一类&#xff0c;所以之前介绍的两种模糊可以称呼为均值降噪和高斯降噪。不过模糊算法对原来的图像特征的…