Linq特取操作之ElementAt,Single,Last,First源码分析
Linq特取操作之ElementAt,Single,Last,First源码分析
一:linq的特取操作
First/FirstOrDefault, Last/LastOrDefault, ElementAt/ElementAtOrDefault, Single/SingleOrDefault
二:First/FirstOrDefault 介绍
解释: 用于返回序列中的第一个值
异常: 如果当前集合没有值的话,如果你取第一个值,会抛出throw Error.NoElements();异常。
public static TSource First<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
if (list.Count > 0)
{
return list[0];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
if (enumerator.MoveNext())
{
return enumerator.Current;
}
}
}
throw Error.NoElements();
}
===> FirstOrDefault <=====
if(list.count==0) return default(TSource)
三:Last/LastOrDefault
默认直接返回序列的最后一个元素。
我们也可以使用Func条件,返回满足指定条件的最后一个元素。
static void Main(string[] args)
{
var nums = new int[] { 4, 3, 2 };
var query = nums.LastOrDefault(i => i % 2 == 0);
}
源码:
=> throw Error.NoElements();
=> return default(TSource);
四: ElementAt/ElementAtOrDefault
ElementAtOrDefault: 这个方便就避免了我们在代码写过多的if判断。【判断是否超出索引】
如果现在用此方法,你就不需要担心这个问题了。。。
源码分析:【效率分析】
public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, int index)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (index >= 0)
{
IList<TSource> list = source as IList<TSource>;
if (list != null)
{
if (index < list.Count)
{
return list[index];
}
}
else
{
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (index == 0)
{
return enumerator.Current;
}
index--;
}
}
}
}
return default(TSource);
}
可以看到,FCL中已经给我们做了一个“索引判断”,所以我们就不需要再代码中进行判断了,这样就方便我们更加的
关于业务逻辑。
五:Single/SingleOrDefault
解释:返回序列中满足指定条件的唯一元素;如果这类元素不存在,则返回默认值;如果有多个元素满足该条件,此方法将引发异常。【三个结果】
First:第一个元素
Single:唯一元素
class Program
{
static void Main(string[] args)
{
var nums = new int[] { 4, 3, 1, 2 };
var query = nums.FirstOrDefault(i => i % 2 == 0); //nums[2];
var query2 = nums.SingleOrDefault(i => i % 2 == 0);
}
}
我们再看源码解释:
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
TSource result = default(TSource);
long num = 0L;
checked
{
foreach (TSource current in source)
{
if (predicate(current))
{
result = current;
num += 1L;
}
}
if (num == 0L)
{
return default(TSource);
}
if (num != 1L)
{
throw Error.MoreThanOneMatch();
}
return result;
}
}
Linq特取操作之ElementAt,Single,Last,First源码分析的更多相关文章
- Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析
Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析 一:Linq的聚合运算 1. 常见的聚合运算:Aggregate,Count, Sum, Distinct,Max, ...
- Linq分组操作之GroupBy,GroupJoin扩展方法源码分析
Linq分组操作之GroupBy,GroupJoin扩展方法源码分析 一. GroupBy 解释: 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值. 查询表达式: var ...
- Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析
Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析 Linq的四种生成运算 DefautIfEmpty,Empty,Range,Repeat 也就是给我们初始化 ...
- Linq基础操作之Select,Where,OrderBy,ThenBy源码分析
Linq基础操作之Select,Where,OrderBy,ThenBy源码分析 二:Select 它是延迟执行.yield有得一拼,因为他们都是生成了一个枚举类. if (source is TSo ...
- Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析
Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析 一:Tolookup 1. 从方法的注解上可以看到,ToLookup也是一个k,v的形式,那么问题来了,它 ...
- Linq集合操作之Intersect,Except,Union源码分析
Linq集合操作之Intersect,Except,Union源码分析 linq的集合运算 常见的集合运算有哪些? 这三个扩展方法在我们实际使用中用的还是非常多的,而且这里还涉及到了“复杂度” 无算法 ...
- Linq限定操作之All,Any,Contains源码分析
Linq限定操作之All,Any,Contains源码分析 linq的限定操作 常见的限定操作: All,Any,Contains 一:All 1. 解释: 确定序列中的所有元素是否满足条件. 从字面 ...
- Linq转换操作之ToArray,ToList,ToDictionary源码分析
Linq转换操作之ToArray,ToList,ToDictionary源码分析 一:linq中的转换运算符 1. ToArray 我们经常用在linq查询上吧. linq只能运用在IEnumerab ...
- Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析
Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析 一: AsParallel [并行化查询] 这个函数的功效就是将计算结果多线程化.[并行计算] =>[多核 ...
随机推荐
- Tkinter Colors(颜色)
Tkinter Colors: Tkinter的代表与字符串的颜色.一般有两种方式来指定Tkinter的颜色 Tkinter的代表与字符串的颜色.一般有两种方式来指定Tkinter的颜色: ...
- 关于where和having的直观理解
一,查询区别 where是对前面select的字段没有要求,直接查询库表的 having是对前面的select的字段有要求,字段已经select出来的 可以用having进行处理 select id, ...
- js给kindeditor添加值
需求:在点击回复按钮时,在kindeditor中添加被回复的用户昵称 html:<textarea name="content" id="mycontent&quo ...
- Windows下安装kibana
1. 下载ElasticSearch https://www.elastic.co/downloads/kibana https://www.elastic.co/downloads/past-rel ...
- CodeFirst(反射+特性)
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy ...
- 【307】◀▶ Python 相关功能实现
目录: 1. Python 实现下载文件 2. 删除文件名中的点 “.” 3. 让 Python 脚本暂停执行的方法 4. 添 1. Python 实现下载文件 使用 urllib 模块提供的 url ...
- ubuntu 安装 rtpengine
摘要 RtpEngine推荐使用Debian系统,可以看出Debian系统的安装是最简单的.我是基于ubuntu18.04安装的.需要注意的是如果你的Ubuntu系统版本太低,安装时会遇到各种的版本太 ...
- visjs使用小记-2.option参数注释说明
对部分参数进行中文说明,后续补充 var options = { nodes:{//节点配置 borderWidth: 1,//节点边框的宽度,单位为px borderWidthSelected: 2 ...
- 基于NodeJS的14款Web框架
摘要: 在几年的时间里,Node.js逐渐发展成一个成熟的开发平台,吸引了许多开发者.有许多大型高流量网站都采用Node.js进行开发,像PayPal, 此外,开发人员还可以使用它来开发一些快速移动W ...
- 阿里云 mysql 远程登录权限
[mysql中配置] 授权法: 1.登录到mysql中,为root进行远程访问的授权,执行下面的命令: mysql> GRANT ALL PRIVILEGES ON *.* TO root@& ...