C# Linq源码分析之Take方法

概要

Take方法作为IEnumerable的扩展方法,具体对应两个重载方法。本文主要分析第一个接收整数参数的重载方法。

源码解析

Take方法的基本定义

public static System.Collections.Generic.IEnumerable Take (this System.Collections.Generic.IEnumerable source, int count);

基本功能是从序列source中,返回指定个数count的相邻元素。

源码分析

Take.cs

public static IEnumerable<TSource> Take<TSource>(this IEnumerable<TSource> source, int count)
{if (source == null){ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);}return count <= 0 ?Empty<TSource>() :TakeIterator<TSource>(source, count);
}

Take方法本身代码很简单, 首先作了一个空序列的检查,如果序列为空,则抛出异常。然后如果count是0,即取前0项相邻元素,等价于什么也不作,直接返回,否则调用TakeIterator方法。

Take.SizeOpt.cs

private static IEnumerable<TSource> TakeIterator<TSource>(IEnumerable<TSource> source, int count)
{Debug.Assert(count > 0);foreach (TSource element in source){yield return element;if (--count == 0) break;}
}

TakeIterator方法并没有像我们之前分析的Where,Select等方法那样,根据功能,定于很多Iterator的派生类来实现具体的功能,而是使用了yield return的方式。

按照count的个数取出对应的元素,以yield return的方式返回。

下面我们使用相同的代码,定义我们自己的扩展方法take 和takeIterator,通过log来搞清楚yield return方式的实现细节。

 public static IEnumerable<TSource> take<TSource>(this IEnumerable<TSource> source, int count)
{Console.WriteLine("take is called !");if (source == null){             ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);}return count <= 0 ?Empty<TSource>() :takeIterator<TSource>(source, count);
}private static IEnumerable<TSource> takeIterator<TSource>(IEnumerable<TSource> source, int count)
{Console.WriteLine("TakeIterator is called !");Debug.Assert(count > 0);foreach (TSource element in source){Console.WriteLine("Enter takeIterator Foreach");yield return element;Console.WriteLine("Return " + element + " from takeIterator Foreach");if (--count == 0) break;}
}

Case 1 不通过toList或foreach循环来调用take的返回值。

  static void Main(string[] args){var list = Enumerable.Range(1,10).take(2);}

执行结果如下:

在这里插入图片描述
我们可以看到takeIterator并未被调用。

Case 2: 通过foreach循环来调用take的返回值

static void Main(string[] args){var list = Enumerable.Range(1,10).take(2);foreach (var item in list){Console.WriteLine("Enter foreach Main function's  foreach");Console.WriteLine("Print " + item + " in Main function");}}

执行结果如下:

在这里插入图片描述
从执行结果可以看出:

  1. takeIterator函数只执行一次,但是会生成一个状态机,用于返回take出来的所有数据;
  2. Main函数中的foreach每次的取值,是从状态机中获取数据,即通过yield return的方式获取。

结论

通过定义具体迭代器实现的延迟加载和通过yield return方式实现的延迟加载,本质上没有区别。

但是实现上略有不同,定义迭代器方式实现的Where或Select等方法,如果没有取值操作,它只是将迭代器对象返回,迭代器对象中保存了迭代方式和源数据序列,对应的方法会被调用。通过yield return方式实现的迭代器,如果没有取值操作,yield return所在的方法不会被调用。

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

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

相关文章

Easys Excel的表格导入(读)导出(写)-----java

一,EasyExcel官网: 可以学习一些新知识: EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 二,为什么要使用easyexcle excel的一些优点和缺点 java解析excel的框架有很多 &#xff1a; poi jxl,存在问题&#xff1a;非常的消耗内存&#xff0c; easyexcel 我们…

Vue项目npm run dev 启动报错TypeError: Cannot read property ‘upgrade‘ of undefined

vue项目启动报错 TypeError: Cannot read property upgrade of undefined 由于我的vue.config.js文件 里面的代理target为空导致的 修改&#xff1a; 结果就可以正常运行了 参考原文&#xff1a; vue项目运行时报Cannot read property ‘upgrade’ of undefined错误_cannot r…

Scratch 之 枪战的枪械画法

大家可以参考百度图片寻找到的AK-47图片&#xff1a;AK47图片 此处我以MK18作为参照&#xff0c;MK18的造型可以在资源中获取 资源链接&#xff1a;https://download.csdn.net/download/leyang0910/88136393 对于不必要的&#xff08;繁琐的&#xff09;线条&#xff0c;我们可…

低代码助力传统制造业数字化转型策略

随着制造强国战略逐步实施&#xff0c;制造行业数字化逐渐进入快车道。提高生产管理的敏捷性、加强产品的全生命周期质量管理是企业数字化转型的核心诉求&#xff0c;也是需要思考的核心价值。就当下传统制造业的核心问题来看&#xff0c;低代码是最佳解决方案&#xff0c;那为…

栈和队列详解

目录 栈 栈的概念及结构&#xff1a; 栈的实现&#xff1a; 代码实现&#xff1a; Stack.h stack.c 队列&#xff1a; 概念及结构&#xff1a; 队列的实现&#xff1a; 代码实现&#xff1a; Queue.h Queue.c 拓展&#xff1a; 循环队列&#xff08;LeetCode题目链接&#xff0…

2023年中国倍率型磷酸铁锂出货量及市场需求分析:插电混动汽车用电池为第一大应用市场[图]

由于新能源锂电池市场的竞争极其激烈&#xff0c;各大电池生产厂商不得不细化研发方向&#xff0c;抢占竞争者少、营利性高的细分专业赛道。因此&#xff0c;“自定义”型单体电池应运而生。其主要分为三个大类&#xff0c;分别为高倍率型电池、长寿命型电池和大容量型电池。这…

uni-app实现图片上传功能

效果 代码 <uni-forms-item name"ViolationImg" label"三违照片 :"><uni-file-picker ref"image" limit"1" title"" fileMediatype"image" :listStyles"listStyles" :value"filePathsL…

74HC595驱动7x11点阵屏(LED-7X11-JHM)DEMO

起因 由于我之前做了一个点阵时钟 &#xff0c;但是无奈LED点阵屏价格比较贵&#xff0c;所以想找一个价格较为便宜的点阵来做便宜一点的点阵方案&#xff0c;再淘宝上看到有那种五毛钱一个的7x11的LED点阵&#xff0c;所以就想着试试搞一下这种点阵屏&#xff0c;这个由于是7…

SpringBoot案例-部门管理-根据id查询

目录 根据页面原型&#xff0c;明确需求 查看接口文档 思路分析 接口功能实现 控制层&#xff08;Controller类&#xff09; 业务层&#xff08;Service类&#xff09; 业务类 业务实现类 持久层&#xff08;Mapper类&#xff09; 接口测试 前后端联调 根据页面原型&…

网易互娱出海之旅:大数据平台上云架构设计与实践

2020 年初&#xff0c;随着网易互娱的海外业务增长与海外数据合规的需求&#xff0c;我们开始了网易互娱大数据离线计算平台迁移出海的工作。前期&#xff0c;我们采取了云主机裸机加上高性能 EBS 块存储的方案。但是&#xff0c;这个方案存储费用高昂&#xff0c;成本是国内自…

百度网盘非会员倍速播放(电脑端)

百度网盘非会员倍速播放&#xff08;电脑端&#xff09; 1. 打开edge浏览器&#xff0c;点击右上角的三个点后&#xff0c;选择“扩展” 2. 选择“管理扩展” 3. 选择“获取MicrosoftEdge扩展” 4. 搜索“Global Speed” 5. 选择Global Speed:视频速度控制&#xff0c;然…

概率论与数理统计:第二、三章:一维~n维随机变量及其分布

文章目录 Ch2. 一维随机变量及其分布1.一维随机变量1.随机变量2.分布函数 F ( x ) F(x) F(x)(1)定义(2)分布函数的性质 (充要条件)(3)分布函数的应用——求概率3.最大最小值函数 2.一维离散型随机变量及其概率分布(分布律)3.一维连续型随机变量及其概率分布(概率密度)4.一般类型…

【MOOC】北京理工大学Python网络爬虫与信息提取慕课答案-综合挑出了一些很难评的慕课测验题

1 Requests库中的get()方法最常用&#xff0c;下面哪个说法正确&#xff1f;‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬…

【数据结构与算法】稀疏数组

文章目录 一&#xff1a;为什么会使用稀疏数组1.1 先看一个实际的需求1.2 基本介绍1.2.1 稀疏数组的处理方法1.2.2 数组的举例说明1.2.3 应用实例1.2.4 整体思路分析二维数组转稀疏数组的思路稀疏数组转原始的二维数组的思路 二&#xff1a;代码实现2.1 创建一个原始的11*11二维…

CMake语法中的PUBLIC、PRIVATE、INTERFACE关键字含义

在CMake语法中&#xff0c;经常见到PUBLIC、PRIVATE、INTERFACE关键字&#xff0c;它们是什么意思呢&#xff1f;下面举例说明。 如上图,说明如下&#xff1a; RIVATE&#xff1a;私有的。生成 libhello-world.so时&#xff0c;只在 hello_world.c 中包含了 hello.h&#xff0…

Vision Transformer模型入门

Vision Transformer模型入门 一、Vision Transformer 模型1&#xff0c;Embedding 层结构详解2&#xff0c;Transformer Encoder 详解3&#xff0c;MLP Head 详解 二、ViT-B/16 网络结构三、Hybrid 模型详解四、ViT 模型搭建参数 一、Vision Transformer 模型 总体三个模块&am…

[Vue] Vue2和Vue3的生命周期函数

vue2有11个生命周期钩子, vue3有8个生命周期钩子 从vue创建、运行、到销毁总是伴随着各种事件, 创建、挂载、更新到销毁。 1.vue2系列生命周期 ⑴【beforecreate】实例创建前。 vue完全创建之前&#xff0c;会自动执行这个函数。 ⑵【Created】实例创建后。 这也是个生命…

商品推荐系统浅析 | 京东云技术团队

一、综述 本文主要做推荐系统浅析&#xff0c;主要介绍推荐系统的定义&#xff0c;推荐系统的基础框架&#xff0c;简单介绍设计推荐的相关方法以及架构。适用于部分对推荐系统感兴趣的同学以及有相关基础的同学&#xff0c;本人水平有限&#xff0c;欢迎大家指正。 二、商品…

Qt扫盲-Qt Model/View 理论总结 [下篇]

Qt Model/View 理论总结 [下篇] 一、处理I tem view 中的选择1. 概念1. 当前项目和已选项目 2. 使用选择 model1. 选择项目2. 读取选区状态3. 更新选区4. 选择 model 中的所有项 二、创建新 model1. 设计一个 model2. 只读示例 model1. model 的尺寸2. model 头和数据 3. 可编辑…

【LeetCode】122. 买卖股票的最佳时机 II - 贪婪算法

目录 2023-8-10 10:29:32 122. 买卖股票的最佳时机 II 2023-8-10 10:29:32 没错&#xff0c;还是用双指针思想来套出来的。 感觉步骤很复杂&#xff0c;还调试了半天。 class Solution {public int maxProfit(int[] prices) {int pre 0;int last 1;int maxProfit 0;int c…