Linq基础操作之Select,Where,OrderBy,ThenBy源码分析
Linq基础操作之Select,Where,OrderBy,ThenBy源码分析
二:Select
它是延迟执行。yield有得一拼,因为他们都是生成了一个枚举类。
if (source is TSource[])
{
return new Enumerable.WhereSelectArrayIterator<TSource, TResult>((TSource[])source, null, selector);
}
可以清楚的看到WhereSelectArrayIterator<TSource, TResult> 是一个枚举类。
WhereSelectArrayIterator<TSource, TResult> => numerable.Iterator<TResult> => IEnumerable<TSource>
大家应该清楚,延迟执行的本质是什么??? 枚举类。
public override bool MoveNext()
{
if (this.state == 1)
{
while (this.index < this.source.Length)
{
TSource arg = this.source[this.index];
this.index++;
if (this.predicate == null || this.predicate(arg))
{
this.current = this.selector(arg);
return true;
}
}
this.Dispose();
}
return false;
}
所以说,大家一定要对foreach这个语法糖有一个清楚的认识。
可以看到,foreach遍历数组的时候,用到了内部的一个ArrayEnumerator枚举类。
三:Where
我们知道where应该是用于筛选操作。
var list = new int[] { 10, 20, 30 };
var query = list.Where(i => i / 20 == 0).ToList();
然后我们来分析一下代码:
我们看到,其实where方法也是用到了内部的一个WhereArrayIterator<TSource> 枚举类,同时我们也看到了一个奇葩的
公共父类Enumerable.Iterator<TSource>,对吧,当我们知道枚举类的时候,你应该重点去查看MoveNext这个方法。
public override bool MoveNext()
{
if (this.state == 1)
{
while (this.index < this.source.Length)
{
TSource tSource = this.source[this.index];
this.index++;
if (this.predicate(tSource))
{
this.current = tSource;
return true;
}
}
this.Dispose();
}
return false;
}
通过这个MoveNext,我们应该非常清楚这个Where的业务逻辑。
四:OrderBy,ThenBy源码分析
var list = new int[] { 10, 20, 30 };
var query = list.OrderByDescending(i => i).ToList();
可以看到OrderBy返回的是一个new OrderedEnumerable<TSource, TKey> 的一个类。
当你从OrderedEnumerable类型上面调用ToList,也就执行了GetEnumerator方法。
也就是说这个方法才是我们排序的关键。
我们发现所谓的orderby方法,其实最后调用的是 EnumerableSorter<TElement>.Sort方法。。
而这个Sort用到了“快速排序”。
《2》ThenBy就是在OrderBy的基础上进行了第二轮排序。
如果大家接触过sql server的话,应该明白二次排序。
一种类似嵌套的方式来做的。
id name age
3 jack 22
1 john 32
2 mary 20
Linq基础操作之Select,Where,OrderBy,ThenBy源码分析的更多相关文章
- Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析
Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析 一:Tolookup 1. 从方法的注解上可以看到,ToLookup也是一个k,v的形式,那么问题来了,它 ...
- Linq分组操作之GroupBy,GroupJoin扩展方法源码分析
Linq分组操作之GroupBy,GroupJoin扩展方法源码分析 一. GroupBy 解释: 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值. 查询表达式: var ...
- Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析
Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析 一:Linq的聚合运算 1. 常见的聚合运算:Aggregate,Count, Sum, Distinct,Max, ...
- Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析
Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析 Linq的四种生成运算 DefautIfEmpty,Empty,Range,Repeat 也就是给我们初始化 ...
- Linq特取操作之ElementAt,Single,Last,First源码分析
Linq特取操作之ElementAt,Single,Last,First源码分析 一:linq的特取操作 First/FirstOrDefault, Last/LastOrDefault, Eleme ...
- Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析
Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析 一: AsParallel [并行化查询] 这个函数的功效就是将计算结果多线程化.[并行计算] =>[多核 ...
- Java基础系列--07_Object类的学习及源码分析
Object: 超类 (1)Object是类层次结构的顶层类,是所有类的根类,超类. 所有的类都直接或者间接的继承自Object类. 所有对象(包括数组)都实现这个类的方法 (2)Object ...
- 第1节 Scala基础语法:scala中的方法源码分析
val list=List(1,2,3,4) list.reduce((x:Int,y:Int)=>x+y)--->list.reduceLeft((x:Int,y:Int)=>x+ ...
- Linq集合操作之Intersect,Except,Union源码分析
Linq集合操作之Intersect,Except,Union源码分析 linq的集合运算 常见的集合运算有哪些? 这三个扩展方法在我们实际使用中用的还是非常多的,而且这里还涉及到了“复杂度” 无算法 ...
随机推荐
- TCP粘包拆包场景
TCP编程底层都有粘包和拆包机制,因为我们在C/S这种传输模型下,以TCP协议传输的时候,在网络中的byte其实就像是河水,TCP就像一个搬运工,将这流水从一端转送到另一端,这时又分两种情况: 1)如 ...
- Embarcadero RAD Studio 2016 Product Approach and Roadmap
delphi 2016 路线图 http://community.embarcadero.com/article/news/16211-embarcadero-rad-studio-2016-pro ...
- flask 常见关系模板代码
以下罗列了使用关系型数据库中常见关系定义模板代码 一对多示例场景:用户与其发布的帖子(用户表与帖子表)角色与所属于该角色的用户(角色表与多用户表)示例代码class Role(db.Model): & ...
- Linux实战教学笔记45:NoSQL数据库之redis持久化存储(一)
第1章 redis存储系统 1.1 redis概述 REmote DIctionary Server(Redis)是一个基于key-value键值对的持久化数据库存储系统.redis和大名鼎鼎的Mem ...
- 一个word小技巧
最近在进行word格式重拍的时候发现了一个有些恶心的事,怎么去匹配文档里面所有的中文呢? 后来通过网络搜索发现了答案,在word中的查找和替换中有一个选项,可以使用通配符进行匹配. 当我们使用 ([一 ...
- 压力测试工具--Siege
Siege是一款开源的压力测试工具,设计用于评估WEB应用在压力下的承受能力.可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行.s ...
- Openssl pkeyutl命令
一.简介 pkeyutl命令能够测试所支持的密钥算法的性能 二.语法 openssl rsautl [-in file] [-out file] [-sigfile file] [-inkey fil ...
- 基于weui的一个小插件
移动端项目当中大量的使用了weui,为了减少工作量,方便修改,自己写了个小插件,暂时只有toast和dialog部分,可能会更新actionSheet等其他部分 更新一个手机端预览的二维码,就直接放项 ...
- GDB调试教程
简介 GDB(GNU debugger)是GNU开源组织发布的一个强大的UNIX下的程序调试工具.可以使用它通过命令行的方式调试程序.它使你能在程序运行时观察程序的内部结构和内存的使用情况.你也可以使 ...
- code1225 搭积木
题目分析:将当前层定义为第h层,共用了n块积木,本层积木数为m,f(h,n,m) 那么可以扩展数两种状态:f(h-1,n-m,m-1),f(h-1,n-m,m+1) 直接搜索可能的数据达到h^m,超时 ...