C# Linq源码分析之Take (一)

概要

在.Net 6 中引入的Take的另一个重载方法,一个基于Range的重载方法。因为该方法中涉及了很多新的概念,所以在分析源码之前,先将这些概念搞清楚。

Take方法基本介绍

public static System.Collections.Generic.IEnumerable Take (this System.Collections.Generic.IEnumerable source, Range range);

新的Take重载方法不再接收整数参数,而是接收一个Range类型的参数。它可以从序列中返回指定范围的连续元素。

注意:该方法只能在.Net 6 或更高版本中使用,我们之前用的.Net 4.7, 4.8或.Net Core 3.1中,都不支持该方法。

Range参数的数据结构

Take重载方法的参数是Range类型,Range本身是一个struct, 表示具有起始索引和结束索引的范围。

Range有两个重要的属性Start和End,表示Range的启始索引值和结束索引值,在Take 方法中只会取到结束索引值的前一个元素。

End和Start的属性的类型值是Index,也是struct结构。包含两个重要属性,Value和IsFromEnd。

IsFromEnd是bool类型,表示是正数还是倒数,例如我们可以写成3…^1 表示从第三个到倒数第一个。

Value是int类型,表示索引值。无论是1 或^1, 索引值都是1。

Take 方法的基本使用

static void Main(string[] args)
{
    Range range = 1..3;
    List<string> list = new List<string> { "A", "B", "C", "D", "E", "F", "G" };
    foreach(var val in list.Take(range))
    {
        Console.WriteLine(val);
    }
}

输出结果是 B 和 C

C#中对Range的定义与Python类似。
C#中可以按照正数的方式设定Range,也可以按照倒数的方式设定,也可以按照正数和倒数的混合方式设定Range。

在这里插入图片描述

上述代码中,我们将Range定义为Range range = ^6…3;,也可以得到相同的结果。

但是需要注意的是,Take方法中的Range必须是有意义的,注意下面的情况:

  • ^1…3, 代人Take将得到空序列,因为无论正数还是倒数,Range的开始值必须小于结尾的值, 在上面例子中 ^1就是6,相当于去从第6个到第3个元素,显然是不合理的,结果为空。
  • 3…^4, 代人Take将得到空序列,该Range等价于取从第3个到第3个元素,结果是空。
  • 无论正数还是倒数,都可以越界,我们写成0…100或 ^100… ^1,都能拿到序列的全部元素,不会抛出越界异常。

Take中使用TryGetNonEnumeratedCount方法实现优化

TryGetNonEnumeratedCount方法的基本定义如下:

public static bool TryGetNonEnumeratedCount (this System.Collections.Generic.IEnumerable source, out int count);

该方法用于在不遍历序列元素的情况的下,获取序列中元素个数。

如果目标序列source实现了 ICollection接口,则需要实现Count属性。因此该函数可以直接获取Count属值,并返回True,输出参数count是序列中的元素个数。

如果目标序列source没有实现ICollection接口,则无法直接获取元素个数,因此该函数返回False,count是0。

Take 在执行过程中,如果我们的Range值设定的是倒数方式,我们就需要知道序列中元素的个数,然后将倒数值变成正数值,最后后按照索引取值。

试想如果目标序列数据量很大,如果可以直接获取序列中元素的个数,就可以避免逐个元数遍历,再获取序列中元素个数,可以实现优化,提高代码运行速度。

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

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

相关文章

mybatis-plus 根据指定字段 批量 删除/修改

mybatis-plus 提供了根据id批量更新和修改的方法,这个大家都不陌生 但是当表没有id的时候怎么办 方案一: 手写SQL方案二: 手动获取SqlSessionTemplate 就是把mybatis plus 干的事自己干了方案三 : 重写 executeBatch 方法结论: mybatis-plus 提供了根据id批量更新和修改的方法,…

【Linux】POSIX信号量和基于环形队列的生产消费者模型

目录 写在前面的话 什么是POSIX信号量 POSIX信号量的使用 基于环形队列的生产消费者模型 写在前面的话 本文章主要先介绍POSIX信号量&#xff0c;以及一些接口的使用&#xff0c;然后再编码设计一个基于环形队列的生产消费者模型来使用这些接口。 讲解POSIX信号量时&#x…

rabbitMQ服务自动停止(已解决

1、 在rabbitmq的sbin目录下操作 rabbitmq-plugins enable rabbitmq_management 2、 自己去rabbitmq_server-3.7.5文件夹下创建一个data&#xff0c;再执行这个命令&#xff08;用自己的目录哈 set RABBITMQ_BASED:\RabbitTools\RabbitMQ\rabbitmq_server-3.7.5\data 然后去配…

执行Lua脚本后一直查询不到Redis中的数据(附带问题详细排查过程,一波三折)

文章目录 执行Lua脚本后一直查询不到Redis中的数据&#xff08;附带详细问题排查过程&#xff0c;一波三折&#xff09;问题背景问题1&#xff1a;Lua脚本无法切库问题2&#xff1a;RedisTemlate切库报错问题3&#xff1a;序列化导致数据不一致问题4&#xff1a;Lua脚本中单引号…

windows系统丢失mfc120u.dll的解决方法

1.mfc120u.dll是什么 mfc120u.dll是Windows操作系统中的一个动态链接库&#xff08;Dynamic Link Library&#xff0c;简称DLL&#xff09;文件。它包含了一些用于运行C程序的函数和其他资源。这个特定的DLL文件是Microsoft Foundation Classes&#xff08;MFC&#xff09;库的…

wireshark界面内容含义

网络分析工具——WireShark的使用&#xff08;超详细&#xff09;_世间繁华梦一出的博客-CSDN博客 wireshark抓包数据&#xff1a;理解与分析_wireshark里面length_ 佚名的博客-CSDN博客

app 自动化测试 - 多设备并发 -appium+pytest+ 多线程

1、appiumpython 实现单设备的 app 自动化测试 启动 appium server&#xff0c;占用端口 4723电脑与一个设备连接&#xff0c;通过 adb devices 获取已连接的设备在 python 代码当中&#xff0c;编写启动参数&#xff0c;通过 pytest 编写测试用例&#xff0c;来进行自动化测试…

python优雅地爬虫!

背景 我需要获得新闻&#xff0c;然后tts&#xff0c;在每天上班的路上可以听一下。具体的方案后期我也会做一次分享。先看我喜欢的万能的老路&#xff1a;获得html内容-> python的工具库解析&#xff0c;获得元素中的内容&#xff0c;完成。 好家伙&#xff0c;我知道我爬…

Data Abstract for .NET and Delphi Crack

Data Abstract for .NET and Delphi Crack .NET和Delphi的数据摘要是一套或RAD工具&#xff0c;用于在.NET、Delphi和Mono中编写多层解决方案。NET和Delphi的数据摘要是一个套件&#xff0c;包括RemObjects.NET和Delphi版本的数据摘要。RemObjects Data Abstract允许您创建访问…

Vue使用jspdf和html2canvas组件库结合导出PDF文件

效果图&#xff1a; 1、安装依赖&#xff1a; npm install html2canvas --save npm install jspdf --save 或 yarn add html2canvas --save yarn add jspdf --save 2、封装全局调用方法&#xff1a;this.$exportPDF(#id,文件名) 新建js文件&#xff1a;/utils/html2Pdf.js&am…

Mysql性能优化:什么是索引下推?

导读 索引下推&#xff08;index condition pushdown &#xff09;简称ICP&#xff0c;在Mysql5.6的版本上推出&#xff0c;用于优化查询。 在不使用ICP的情况下&#xff0c;在使用非主键索引&#xff08;又叫普通索引或者二级索引&#xff09;进行查询时&#xff0c;存储引擎…

QtCreator中设置自定义注释格式

QtCreator--工具--选项--文本编辑器--片段--组:C--添加 在其中添加一个key为&#xff1a;header&#xff0c;value如下图的组合&#xff1a; /*! ProjName : %{CurrentProject:Name}* FileName : %{CurrentDocument:FileName}* Brief : * Details : * Aut…

(三) 搞定SOME/IP通信之CommonAPI库

本章主要介绍在SOME/IP通信过程中的另外一个IPC通信利剑&#xff0c;CommonAPI库&#xff0c;文章将从如下几个角度让读者了解什么是CommonAPI, 以及库在实际工作中的作用 文中资源&#xff1a;vsomeipcommonapi指导文档与demo源码 SOME/IP通信之CommonAPI CommonAPI库是什么C…

Java虚拟机(JVM):堆溢出

一、概念 Java堆溢出&#xff08;Java Heap Overflow&#xff09;是指在Java程序中&#xff0c;当创建对象时&#xff0c;无法分配足够的内存空间来存储对象&#xff0c;导致堆内存溢出的情况。 Java堆是Java虚拟机中用于存储对象的一块内存区域。当程序创建对象时&#xff0c…

设计模式之简单工厂模式

一、概述 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂模式使一个类的实例化延迟到其子类。 简单工厂模式&#xff1a;又叫做静态工厂方法模式&#xff0c;是由一个工厂对象决定创建出哪一种产品类的实例。 二、适用性 1.当一个类不知道它所必须…

MySQL 账号权限

mysql 在安装好后&#xff0c;默认是没有远端管理账号。 一、账号管理 1. 查看账号列表 MySQL用户账号和信息存储在名为 mysql 的数据库中。一般不需要直接访问 mysql 数据库和表&#xff0c;但有时需要直接访问。例如&#xff0c;查看数据库所有用户账号列表时。 USE mysql; …

Matplotlib数据可视化(二)

目录 1.rc参数设置 1.1 lines.linestype取值 1.2 lines.marker参数的取值 1.3 绘图中文预设 1.4 示例 1.4.1 示例1 1.4.2 示例2 1.rc参数设置 利用matplotlib绘图时为了让绘制出的图形更加好看&#xff0c;需要对参数进行设置rc参数设置。可以通过以下代码查看matplotli…

揭秘!体育比赛是如何快人一步购票的

最近&#xff0c;各类体育赛事正如火如荼的进行中&#xff0c;作为资深体育迷&#xff0c;看着赛场上的英雄们正在为荣誉和胜利而拼搏&#xff0c;内心也跟着激情澎湃起来。 为了享受精彩纷呈的赛事&#xff0c;越来越多体育迷选择亲临现场&#xff0c;感受更真实的比赛氛围&a…

VR仿真实训系统编辑平台赋予老师更多自由和灵活性

为了降低院校教师在VR虚拟现实方面应用的门槛&#xff0c;VR公司深圳华锐视点融合多年的VR虚拟仿真实训系统制作经验&#xff0c;制作了VR动物课件编辑器&#xff0c;正在逐渐受到师生们的关注和应用。 简单来说&#xff0c;VR畜牧专业课件编辑器是一种可以制作虚拟现实动物教学…

【WPF】 本地化的最佳做法

【WPF】 本地化的最佳做法 资源文件英文资源文件 en-US.xaml中文资源文件 zh-CN.xaml 资源使用App.xaml主界面布局cs代码 App.config辅助类语言切换操作类资源 binding 解析类 实现效果 应用程序本地化有很多种方式&#xff0c;选择合适的才是最好的。这里只讨论一种方式&#…