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的集合运算 常见的集合运算有哪些? 这三个扩展方法在我们实际使用中用的还是非常多的,而且这里还涉及到了“复杂度” 无算法 ...
随机推荐
- centos 和KVM安装
- Python格式符说明
格式化输出 例如我想输出 我的名字是xxxx 年龄是xxxx name = "Lucy"age = 17print("我的名字是%s,年龄是%d"%(name, ...
- sublime 安装插件
安装Package Control 在安装插件之前,需要让sublime安装Package Control.打开Sublime Text的控制台,快捷键ctrl + ~,在控制台中输入以下代码. im ...
- ubuntu 初始设置备忘
配置静态网络 vim /etc/network/interfaces auto eth0 #iface eth0 inet dhcp iface eth0 inet static address x. ...
- Build/Run Instructions for Codec Engine Examples
General Information This page explains how to build the examples provided in the Codec Engine (CE) p ...
- jenkins-为什么要持续集成
持续集成(Continuous Integration),也就是我们经常说的 CI,是现代软件开发技术的基础.本文论述了当前软件开发过程中存在的问题,讲解了持续集成.持续集成服务器的概念,最终探讨了为 ...
- easyui 验证框
转自:http://blog.csdn.net/pqszq1314/article/details/25896163 例如 校验输入框只能录入0-1000之间 最多有2位小数的数字 表单<inp ...
- centos7 安装VMware Tools 遇到的一系列问题的解决方案
先部署源:http://www.cnblogs.com/jiu0821/p/8074463.html VMware Tools安装方法参考:http://www.cnblogs.com/jiu0821 ...
- JRE,JVM,JDK
JRE,JVM,JDK的关系.JRE(Java Runtime Environment)java运行环境,我们可以把它看成是一个操作系统.也就是说JRE提供了Java执行的软件平台. JVM (Jav ...
- jmeter 读取mysql数据库
业务背景 当我们用jmeter进行压测,或者造数据的时候,我们可能希望每次请求的参数都是随机的.如果从一个文件里读取,很难达到要求.jmeter提供了一套读取数据库的组件,能满足部分要求.但性能不好, ...