[C#] 基于 yield 语句的迭代器逻辑懒执行

众所周知, C# 可以通过 yield 语句来快速向 IEnumerator 或者 IEnumerable 类型的方法返回值返回一个元素. 但它还有另外一个特性, 就是其内部逻辑的懒执行. 每两个 yield 语句之间的逻辑都是一个状态, 只有在调用迭代器的 MoveNext 方法后, 才会执行下一个状态的逻辑.

在文章中, 编译后的代码已经经过简化和删减, 以便于理解


迭代器方法的懒执行

举一个简单的例子:

IEnumerator SomeLogic()
{
    Console.WriteLine("hello world");
    yield return null;
    Console.WriteLine("fuck you world");
}

在调用的时候, 逻辑并不会被立即执行, 只有对其返回的迭代器调用 MoveNext 的时候, 才会继续执行.

var enumerator = SomeLogic();

enumerator.MoveNext();   // 打印 hello world
enumerator.MoveNext();   // 打印 fuck you world

迭代器方法的编译

在 C# 中, 使用了 yield 语句的, 返回 IEnumerator 或 IEnumerable 的方法, 会由编译器生成一个迭代器或可迭代类型, 在类型的内部包含该方法的逻辑.

例如上面提到的代码, 它会被编译成大概这样:

IEnumerator SomeLogic()
{
    return new SomeLogicEnumerator();
}


private sealed class SomeLogicEnumerator : IEnumerator, IDisposable
{
    private int state;
    private object current;

    object IEnumerator.Current
    {
        get
        {
            return current;
        }
    }

    public SomeLogicEnumerator(int state)
    {
        this.state = state;
    }

    void IDisposable.Dispose()
    {
    }

    private bool MoveNext()
    {
        int num = state;
        if (num != 0)
        {
            if (num != 1)
            {
                return false;
            }
            state = -1;
            Console.WriteLine("AWA");
            return false;
        }
        state = -1;
        Console.WriteLine("QWQ");
        current = null;
        state = 1;
        return true;
    }

    bool IEnumerator.MoveNext()
    {
        //ILSpy generated this explicit interface implementation from .override directive in MoveNext
        return this.MoveNext();
    }

    void IEnumerator.Reset()
    {
        throw new NotSupportedException();
    }
}

我们可以看到, 在这个迭代器类型中, 有一个 state 字段存储了当前的状态, 而在 MoveNext 被调用时, 会切换当前状态, 然后根据当前状态执行对应逻辑.

当然, 如果你的迭代器逻辑稍微长一些, 它也是可以处理的.

IEnumerator SomeLogic()
{
	Console.WriteLine("QWQ");
	yield return 1;
	Console.WriteLine("AWA");
	yield return 2;
	Console.WriteLine("QJFD");
	yield return 3;
	Console.WriteLine("JWOEIJFOIWE");
}

它的 MoveNext 就变成了这样:

private bool MoveNext()
{
    switch (state)
    {
        case 0:
            Console.WriteLine("QWQ");
            current = 1;
            state = 1;
            return true;
        case 1:
            Console.WriteLine("AWA");
            current = 2;
            state = 2;
            return true;
        case 2:
            Console.WriteLine("QJFD");
            current = 3;
            state = 3;
            return true;
        case 3:
            state = -1;
            Console.WriteLine("JWOEIJFOIWE");
            return false;
        default:
            return false;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

17.(vue3.x+vite)组件间通信方式之作用域插槽

前端技术社区总目录(订阅之前请先查看该博客) 示例效果 作用域插槽 父组件中的插槽内容是无法访问到子组件中的数据的,而作用域插槽就是解决获取子组件数据。 父组件代码 <template><div><div>父组件--Hello World!</div><Child>

【普中开发板】基于51单片机电子钟闹钟设计( proteus仿真+程序+设计报告+讲解视频)

【普中开发板】基于51单片机电子钟闹钟数码管显示设计( proteus仿真程序设计报告讲解视频&#xff09; Proteus 仿真&#xff1a;Proteus 8.16 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;P03 51单片机电子钟闹钟 1. 主要功能&a…

RT-Thread Studio + STM32CubeMx 联合开发

RT-Thread Studio STM32CubeMx 联合开发 背景参考 背景 使用RTThreadNano开发工具&#xff1a; RTThread Studio&#xff1a;官方工具&#xff0c;对RTThread系统兼容最好&#xff0c;可以对不同的MCU平台进行开发&#xff0c;包括但不限于以下平台 STM32GD32IAR STM32CubeI…

mac 安装nvm以及切换node版本详细步骤

1、nvm介绍&#xff08;node版本管理工具&#xff09; nvm 可以让你通过命令行快速安装和使用不同版本的node 有时候项目太老&#xff0c;node版本太高,执行npm install命令会报错,可以借助nvm切换低版本的node。 2、安装nvm 在终端执行安装命令 curl -o- https://raw.gith…

Vue router深入学习

Vue router深入学习 一、单页应用程序介绍 1.概念 单页应用程序&#xff1a;SPA【Single Page Application】是指所有的功能都在一个html页面上实现 2.具体示例 单页应用网站&#xff1a; 网易云音乐 https://music.163.com/ 多页应用网站&#xff1a;京东 https://jd.co…

销售技巧培训之如何提升化妆品销售技巧

销售技巧培训之如何提升化妆品销售技巧 一、引言 在当今竞争激烈的化妆品市场&#xff0c;销售人员需要掌握一定的技巧才能吸引顾客&#xff0c;提高销售业绩。本文将通过实际案例&#xff0c;探讨化妆品销售的有效技巧&#xff0c;帮助销售人员提升业绩。 二、案例分析 案…

jstree组件的使用详细教程,部分案例( PHP / fastAdmin )

jstree 组件的使用。 简介&#xff1a;JsTree是一个jquery的插件&#xff0c;它提交一个非常友好并且强大的交互性的树&#xff0c;并且是完全免费或开源的&#xff08;MIT 许可&#xff09;。Jstree技持Html 或 json格式的的数据&#xff0c; 或者是ajax方式的动态请求加载数…

宁夏康源肛肠医院发声 有劳肠道了

肠道先生&#xff1a; 你好&#xff0c;我是宁夏康源肛肠医院&#xff0c;今日书信一封&#xff0c;旨在请先生出山&#xff0c;救万民健康于水火。当前&#xff0c;支原体肺炎肆虐&#xff0c;且尚无疫苗可预&#xff0c;值此危急之际&#xff0c;正是肠道先生免疫力发挥功力…

高速吹风筒方案中光耦的作用和原理--【其利天下技术】

我们都知道高速风筒方案中&#xff0c;采用了光耦作为隔离元器件&#xff0c;那么光耦是个什么特性的元件呢&#xff1f;它用来隔离什么东西呢&#xff1f;它又是如何做到隔离作用的呢&#xff1f;带着这样的疑问&#xff0c;我们对光耦做一番研究吧。 其利天下技术--光耦 &am…

AutoAnimate动画库,仅需一行代码

插件官网,支持react,vue AutoAnimate - Add motion to your apps with a single line of code 自动加动画原理 AutoAnimate 加动画的原理也很简单&#xff0c;监听绑定的 DOM 节点里 DOM 结构变化&#xff0c;自动添加对应的过渡动画&#xff1a; 增加子节点 > 渐入动画…

芳村金融茶最新进展——00后老板被带走调查

芳村 芳村茶叶的发展史可以追溯到1858年&#xff0c;当时芳村花地的翠林花园一角&#xff0c;已经有茶叶商行和制茶作坊。然而&#xff0c;芳村真正以花闻名&#xff0c;可以说是“先有花后有茶”&#xff0c;是花带动了茶的发展。在20世纪70年代左右&#xff0c;芳村和山村主要…

【论文阅读】Answering Label-Constraint Reachability in Large Graphs

Xu K, Zou L, Yu J X, et al. Answering label-constraint reachability in large graphs[C]//Proceedings of the 20th ACM international conference on Information and knowledge management. 2011: 1595-1600. Abstract 在本文中&#xff0c;我们研究了可达性查询的一种变…

光伏储能数据难题很棘手?架构升级很迷茫?来看三大真实案例

近年来&#xff0c;随着光伏储能装置的增加&#xff0c;设备数量和测点数量也在相应增加&#xff0c;数据采集频率也在不断提高&#xff0c;由此产生的时序数据量越来越庞大&#xff0c;对数据处理和实时分析的要求也越来越高。同时光伏储能系统需要长期保存大量的历史数据&…

IDEA小技巧

目录 1. IDEA自动添加注释 创建类的时候自动添加注释 创建函数、方法的注释 1. IDEA自动添加注释 参考文档&#xff1a;idea java 自动添加文件注释 idea新建类自动注释_mob6454cc73c728的技术博客_51CTO博客 【操作工具】IDEA创建类及已有类添加注释-详细操作_idea设置创建…

Python Selenium3 自动化测试实战:构建高效测试项目

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在当今软件开发领域&#xff0c;自动化测试成为…

硅片制作工艺-详细图文版

首先将多晶硅和掺杂剂放入单晶炉内的石英坩埚中&#xff0c;将温度升高至1000多度&#xff0c;得到熔融状态的多晶硅。 硅锭生长是一个将多晶硅制成单晶硅的工序&#xff0c;将多晶硅加热成液体后&#xff0c;精密控制热环境&#xff0c;成长为高品质的单晶。 相关概念&#xf…

【JavaScript】JavaScript中的GC算法

1、内存管理 内存&#xff1a;由可读写单元组成&#xff0c;标识一片可操作的空间 管理&#xff1a; 认为的去操作一篇空间的申请、使用和释放 内存管理&#xff1a;开发者主动申请空间、使用空间、释放空间 管理流程&#xff1a; 申请-使用-释放 // 申请 let obj {} //使…

【教程】app备案流程简单三部曲即可完成

APP备案流程包括以下步骤&#xff1a; 1. 开发者实名认证&#xff1a;在提交备案申请之前&#xff0c;开发者需要通过移动应用开发平台进行实名认证。这个步骤需要提供身份证号码、姓名、联系方式等信息&#xff0c;并上传相关证件照片或扫描件。 2. 应用信息登记&#xff1a…

DevOps搭建(九)-Jenkins实现基础CI、CD详细操作

1、创建可运行SpringBoot项目 1.1、创建一个新工程 在idea里创建一个项目,这里叫devops-test,如下图: String Boot版本要选择2.x的,依赖直选中Spring Web选项即可: 修改pom.xml文件,在build标签中增加如下内容,目的是简化jar包名称。 <finalName>devops-test&l…
最新文章