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 关键字可以轻松地实现深度优先遍历、广度优先遍历等不同的遍历逻辑,将遍历过程中节点的值逐个返回给调用者。
相关文章:

C# yield 关键字
文章目录 前言一、yield 关键字的语法形式及使用场景(一)yield return(二)yield break 二、yield 关键字的工作原理三、yield 关键字的优势与应用场景(一)优势(二)应用场景 前言 在 …...

SpringBoot开发——结合Nginx实现负载均衡
文章目录 负载均衡介绍介绍Nginx实现负载均衡的示例图:负载均衡策略1.Round Robin:2.Least Connections:3.IP Hash :4.Generic Hash:5.Least Time (NGINX Plus only)6.Random:Nginx+SpringBoot实现负载均衡环境准备Nginx 配置负载均衡测试负载均衡介绍 介绍 在介绍Nginx的负…...

RabbitMQ在手动消费的模式下设置失败重新投递策略
最近在写RabbitMQ的消费者,因为业务需求,希望失败后重试一定次数,超过之后就不处理了,或者放入死信队列。我这里就达到重试次数后就不处理了。本来以为很简单的,问了kimi,按它的方法配置之后,发…...

TsingtaoAI具身智能高校实训方案通过华为昇腾技术认证
日前,TsingtaoAI推出的“具身智能高校实训解决方案-从AI大模型机器人到通用具身智能”基于华为技术有限公司AI框架昇思MindSpore,完成并通过昇腾相互兼容性技术认证。 TsingtaoAI&华为昇腾联合解决方案 本项目“具身智能高校实训解决方案”以实现高…...

【Linux】线程池设计 + 策略模式
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 线程池 1-1 ⽇志与策略模式1-2 线程池设计1-3 线程安全的单例模式1-3-1 什么是单例模式1-3-2 单例模式的特点1-3-3 饿汉实现⽅式和懒汉实现⽅式1-3-4 饿汉…...

网络原理(一):应用层自定义协议的信息组织格式 HTTP 前置知识
目录 1. 应用层 2. 自定义协议 2.1 根据需求 > 明确传输信息 2.2 约定好信息组织的格式 2.2.1 行文本 2.2.2 xml 2.2.3 json 2.2.4 protobuf 3. HTTP 协议 3.1 特点 4. 抓包工具 1. 应用层 在前面的博客中, 我们了解了 TCP/IP 五层协议模型: 应用层传输层网络层…...

Python-链表数据结构学习(1)
一、什么是链表数据? 链表是一种通过指针串联在一起的数据结构,每个节点由2部分组成,一个是数据域,一个是指针域(存放下一个节点的指针)。最后一个节点的指针域指向null(空指针的意思࿰…...
性能优化经验:关闭 SWAP 分区
关闭 SWAP 分区,特别是在性能敏感场景(如 Elasticsearch 服务)中,主要与 SWAP 的工作机制和对应用性能的影响有关。以下是详细原因: 1. SWAP 的工作机制导致高延迟 SWAP 是什么: SWAP 分区是系统将物理内存…...

SpringBoot小知识(2):日志
日志是开发项目中非常重要的一个环节,它是程序员在检查程序运行的手段之一。 1.日志的基础操作 1.1 日志的作用 编程期调试代码运营期记录信息: * 记录日常运营重要信息(峰值流量、平均响应时长……) * 记录应用报错信息(错误堆栈) * 记录运维过程数据(…...
java虚拟机——jvm是怎么去找垃圾对象的
JVM(Java虚拟机)通过特定的算法和机制来查找和识别垃圾对象,以便进行垃圾回收。以下是JVM查找垃圾对象的主要方法和步骤: 一、可达性分析法 JVM使用可达性分析法来识别垃圾对象。这种方法从一组称为“GC Roots”的对象作为起始点…...

Macos远程连接Linux桌面教程;Ubuntu配置远程桌面;Mac端远程登陆Linux桌面;可能出现的问题
文章目录 1. Ubuntu配置远程桌面2. Mac端远程登陆Linux桌面3. 可能出现的问题1.您用来登录计算机的密码与登录密钥环里的密码不再匹配2. 找不到org->gnome->desktop->remote-access 1. Ubuntu配置远程桌面 打开设置->共享->屏幕共享。勾选允许连接控制屏幕&…...

hadoop_HA高可用
秒懂HA HA概述HDFS-HA工作机制工作要点元数据同步参数配置手动故障转移自动故障转移工作机制相关命令 YARN-HA参数配置自动故障转移机制相关命令 附录Zookeeper详解 HA概述 H(high)A(avilable): 高可用,意味着必须有容错机制,不能因为集群故障…...
【MySQL】MySQL中的函数之JSON_ARRAY_APPEND
在 MySQL 8.0 及更高版本中,JSON_ARRAY_APPEND() 函数用于在 JSON 数组的指定位置追加一个或多个值。这个函数非常有用,特别是在你需要在 JSON 数组的末尾或特定位置添加新的元素时。 基本语法 JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ..…...
torch.is_nonzero(input)
torch.is_nonzero(input) input: 输入张量 若输入是 不等于零的单元素张量 则返回True,否则返回False 不等于零的单元素张量:torch.tensor([0.]) 或 torch.tensor([0]) 或 torch.tensor([False])单元素张量: 只有一个数 的张量 import torch print(t…...
文本搜索程序(Qt)
头文件 #ifndef TEXTFINDER_H #define TEXTFINDER_H#include <QWidget> #include <QFileDialog> #include <QFile> #include <QTextEdit> #include <QLineEdit> #include <QTextStream> #include <QPushButton> #include <QMess…...
使用 Python 剪辑视频的播放速度
要使用 Python 调整视频的播放速度,可以利用 moviepy 库中的 fx(特效)模块来实现这一功能。通过 moviepy.editor 中的 VideoFileClip 类和 fx.speedx 函数,可以轻松地调整视频的播放速度。 安装 moviepy 首先,确保已…...

深入理解计算机系统,源码到可执行文件翻译过程:预处理、编译,汇编和链接
1.前言 从一个高级语言到可执行程序,要经过预处理、编译,汇编和链接四个过程。大家可以思考下,为什么要有这样的过程? 我们学习计算机之处,就应该了解到,计算机能够识别的只有二进制语言(这是…...
Linux开发者的CI/CD(11)jenkins变量
文章目录 1. **环境变量 (Environment Variables)**常见的环境变量:示例:2. **构建参数 (Build Parameters)**常见的构建参数类型:示例:3 **在 `stages` 块内定义局部变量**示例:使用 `script` 步骤定义局部变量4 变量引用陷阱在 Jenkins 中,变量是自动化流程中非常重要的…...
深度学习视频编解码开源项目介绍【持续更新】
DVC (Deep Video Compression) 介绍:DVC (Deep Video Compression) 是一个基于深度学习的视频压缩框架,它的目标是通过深度神经网络来提高视频编码的效率,并降低比特率,同时尽可能保持视频质量。DVC 是一个端到端的神经网络模型&…...
Canva迁移策略深度解析:应对每日5000万素材增长,从MySQL到DynamoDB的蜕变
随着数字化设计的蓬勃发展,Canva作为一款备受欢迎的在线设计平台,面临着日益增长的用户生成内容挑战。每天,平台上新增的素材数量高达5000万,这对数据库系统提出了前所未有的要求。为了应对这一挑战,Canva决定对其数据…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...