C# Linq源码分析之Take (二)
概要
本文主要分析Linq中Take带Range参数的重载方法的源码。对于其中的一些关于Range或序列的新概念,不再赘述,请参看C# Linq源码分析之Take (一)
源码分析
基于Range参数的Take重载方法,主要分成两部分实现,一部分是Range中的开始和结束索引都是正数的情况例如取第一个到第三个元素的情况;另一部分是开始或结束索引中有倒数的情况,例如取倒数第三个到倒数第一个的情况。
本文着重分析Range中的正数情况。
public static IEnumerable<TSource> Take<TSource>(this IEnumerable<TSource> source, Range range)
{if (source == null){ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);}Index start = range.Start;Index end = range.End;bool isStartIndexFromEnd = start.IsFromEnd;bool isEndIndexFromEnd = end.IsFromEnd;int startIndex = start.Value;int endIndex = end.Value;Debug.Assert(startIndex >= 0);Debug.Assert(endIndex >= 0);if (isStartIndexFromEnd){if (startIndex == 0 || (isEndIndexFromEnd && endIndex >= startIndex)){return Empty<TSource>();}}else if (!isEndIndexFromEnd){return startIndex >= endIndex? Empty<TSource>(): TakeRangeIterator(source, startIndex, endIndex);}return TakeRangeFromEndIterator(source, isStartIndexFromEnd, startIndex, isEndIndexFromEnd, endIndex);
}
- 检查源序列是否为空,如果为空,直接抛出异常;
- 获取Range的启始和结束的索引值,以及索引值是正数还是倒数的bool值;
- 如果开始索引值是倒数,以下几种情况返回空序列:
(a)开始索引是^0, 倒数第0个,显然不合理
(b)Range形如 ^1… ^3的情况,假设有10个元素, ^1… ^3相当于取从第10个到第7个,显然是不合理。应该是从第7个到第10个
(c)Range形如 ^2 … ^2因为开始和结束索引相同,中间没有间隔元素,该种情况也不合理 - 在Range中的开始和结束索引都不是倒数的情况下,如果开始索引大于结束索引,即Range形如2…1,返回空序列;否则调用TakeRangeIterator方法,完成具体取值操作;
- 对于合理的Range倒数情况,例如形如 ^3… ^1 , 3… ^1 或 ^3 … 10 这些情况,执行最后的TakeRangeFromEndIterator方法。
TakeRangeIterator方法
TakeRangeIterator方法用于处理Range中的开始和结束索引都是正数的情况。该方法位于Take.SizeOpt文件中。通过yield return/break的方式管理迭代过程。
private static IEnumerable<TSource> TakeRangeIterator<TSource>(IEnumerable<TSource> source, int startIndex, int endIndex)
{Debug.Assert(source != null);Debug.Assert(startIndex >= 0 && startIndex < endIndex);using IEnumerator<TSource> e = source.GetEnumerator();int index = 0;while (index < startIndex && e.MoveNext()){++index;}if (index < startIndex){yield break;}while (index < endIndex && e.MoveNext()){yield return e.Current;++index;}
}
- 创建迭代器e,采用using方式,在函数执行完成后,自动释放内存空间;
- 如果Range中的索引数据和source序列中的元素个数不匹配,例如指定从第三个元素开始取,但是数列里面只有两个元素,返回yield break,关闭状态机,注意,此种情况并不会抛出越界异常;
- 按照索引范围,通过迭代器e取值,创建状态机,通过yield return方式返回。
TakeRangeFromEndIterator方法
TakeRangeIterator方法用于处理Range中的开始和结束索引存在倒数的情况。该方法位于Take.cs文件中。通过yield return/break的方式管理迭代过程。
该方法篇幅较长,将在C# Linq源码分析之Take (三)中详细分析其源码。
相关文章:
C# Linq源码分析之Take (二)
概要 本文主要分析Linq中Take带Range参数的重载方法的源码。对于其中的一些关于Range或序列的新概念,不再赘述,请参看C# Linq源码分析之Take (一) 源码分析 基于Range参数的Take重载方法,主要分成两部分实现&#x…...
FPGA控制RGB灯WS2812B
文章目录 FPGA控制RGB灯WS2812B1、简介1.1水一水1.2程序完成目标1.3项目工程结构 2、代码3、仿真代码4、结果展示 FPGA控制RGB灯WS2812B 1、简介 1.1水一水 最近在学习WS2812B手册,是一个简单的协议编写,做的时间也算是比较久,相对做出了一…...
【Linux】【驱动】应用层和驱动层传输数据
【Linux】【驱动】应用层和驱动层传输数据 绪论1.如果我在应用层使用系统0 对设备节点进行打开,关闭,读写等操作会发生什么呢? 2 我们的应用层和内核层是不能直接进行数据传输的3 驱动部分的代码4 应用代码5 编译以及运行代码 绪论 Linux一切皆文件! 文…...
【第二阶段】kotlin函数引用
针对上篇传入函数参数我们也可以重新定义一个函数,然后在main中调用时传入函数对象 lambda属于函数类型的对象,需要把普通函数变成函数类型的对象(函数引用),使用“::” /*** You can edit, ru…...
sip网络号角喇叭 sip音柱 POE供电广播音箱 ip网络防水对讲终端 sip网络功放
SV-7042TP网络号角喇叭 一、描述 SV-7042TP是我司的一款SIP网络号角喇叭,具有10/100M以太网接口,内置有一个高品质扬声器,将网络音源通过自带的功放和喇叭输出播放,可达到功率30W。SV-7042TP作为SIP系统的播放终端,可…...
【网络】传输层——TCP(滑动窗口流量控制拥塞控制延迟应答捎带应答)
🐱作者:一只大喵咪1201 🐱专栏:《网络》 🔥格言:你只管努力,剩下的交给时间! 上篇文章对TCP可靠性机制讲解了一部分,这篇文章接着继续讲解。 🎨滑动窗口 在…...
Electron教程_编程入门自学教程_菜鸟教程-免费教程分享
教程简介 Electron是一个是使用JavaScript,HTML和CSS构建跨平台的桌面应用程序框架。 Electron 通过将 Chromium 和 Node.js 合并到同一个运行时环境中,并将其打包为 Mac,Windows 和 Linux 系统下的应用来实现这一目的。 Electron入门教程 …...
LVS负载均衡DR(直接路由)模式
在LVS(Linux Virtual Server)负载均衡中的DR(Direct Routing)模式下,数据包的流向如下: 客户端发送请求到负载均衡器(LVS)的虚拟IP(VIP)。负载均衡器&#x…...
14 anaconda+pycharm环境管理以及源管理
文章目录 环境管理博主使用的环境环境设置conda常用指令pycharm与环境的连接(新2023版本后)设置国内镜像(源管理)常用操作 环境管理 博主使用的环境 Anaconda3-2023.03-Windows-x86_64 pycharm-professional-2023.2 环境设置 …...
【C语言程序设计】C语言基本数据类型与表达式(思考题)
思考题 1、C语言的主要特点有哪些? ①简单紧凑、灵活方便,②是结构化的语言,③运算符丰富,④是一种高效的语言,⑤可直接对硬件进行操作,⑥具有较好的可移植性。 高效性:C语言是一种高级编程语言…...
Linux 网络发包流程
哈喽大家好,我是咸鱼 之前咸鱼在《Linux 网络收包流程》一文中介绍了 Linux 是如何实现网络接收数据包的 简单回顾一下: 数据到达网卡之后,网卡通过 DMA 将数据放到内存分配好的一块 ring buffer 中,然后触发硬中断CPU 收到硬中…...
Python web实战之Django的AJAX支持详解
关键词:Web开发、Django、AJAX、前端交互、动态网页 今天和大家分享Django的AJAX支持。AJAX可实现在网页上动态加载内容、无刷新更新数据的需求。 1. AJAX简介 AJAX(Asynchronous JavaScript and XML)是一种在网页上实现异步通信的技术。通过…...
spring boot实现实体类参数自定义校验
安装依赖项 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>1、新建实体类 Data public class UserEntity {private String name;private Integer age;…...
网络安全威胁与防御策略
第一章:引言 随着数字化时代的快速发展,网络已经成为人们生活和工作中不可或缺的一部分。然而,网络的广泛应用也引发了一系列严峻的网络安全威胁。恶意软件、网络攻击、数据泄露等问题层出不穷,给个人和企业带来了巨大的风险。本文…...
C++:哈希表——模拟散列表
模拟散列表 维护一个集合,支持如下几种操作: 1.“I x”,插入一个数x 2.“Q x”,询问数x是否在集合中出现过 现在要进行N次操作,对于每个询问操作输出对应的结果 输入格式 第一行包含整数N,表示操作数量 …...
项目配置中心介绍
目录 什么是配置中心 为什么要有配置中心 配置中心的做法(读取和通知) 配置中心优点: 常用的配置中心中间件 什么是配置中心 配置中心就是用来管理项目当中所有配置的系统,也是微服务系统当中不可或缺的一部分。项目的配置文件不放到本地…...
14-案例:购物车
综合案例-购物车 需求说明: 1. 渲染功能 v-if/v-else v-for :class 2. 删除功能 点击传参 filter过滤覆盖原数组 3. 修改个数 点击传参 find找对象 4. 全选反选 计算属性computed 完整写法 get/set 5. 统计 选中的 总价 和 数量 计算属性conputed reduce条件求和 6. 持久化到本…...
上海市青少年算法2023年2月月赛(丙组)
上海市青少年算法2023年2月月赛(丙组)T1 格式改写 题目描述 给定一个仅由拉丁字符组成字符序列,需要改写一些字符的大小写,使得序列全部变成大写或全部变成小写,请统计最少修改多少个字符才能完成这项任务。 输入格式 一个字符序列:保证仅由拉丁字符构成 输出格式 单个整…...
jetpack5.0.2 已经安装了 cudnn 和 tensorrt
在平台 jetson Xavier NX 中想使用 cudnn 和 tensorrt。然后自己下载了相应包并解压,拷贝,编译 安装 cudnn 1.下载对应包文件,例如:cudnn-linux-sbsa-8.4.1.50_cuda11.6-archive.tar.xz 2.解压,移动到解压目录&#…...
我的编程语言学习笔记
前言 作为一名编程初学者,我深知学习编程需要不断积累和记录。在这篇博客文章中,我将分享一些我在学习C/C编程语言过程中记录的常用代码、特定函数、复杂概念以及特定功能。希望能与大家一起切磋进步! 常用代码: 1. 输入输出操作…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
