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的集合运算 常见的集合运算有哪些? 这三个扩展方法在我们实际使用中用的还是非常多的,而且这里还涉及到了“复杂度” 无算法 ...
随机推荐
- 深入浅出 Java Concurrency (7): 锁机制 part 2 AQS
在理解J.U.C原理以及锁机制之前,我们来介绍J.U.C框架最核心也是最复杂的一个基础类:java.util.concurrent.locks.AbstractQueuedSynchronizer ...
- 浪潮openStack云
- leetcode744
public class Solution { public char NextGreatestLetter(char[] letters, char target) { //a-97 z-122 v ...
- 我的Linux之路——windows10用WMware安装CentOS6.9 虚拟机详细步骤
出自:http://blog.51cto.com/13438667/2059926 一.安装环境 windows10操作系统物理机VMware Workstation 软件(可以在网上下载)CentO ...
- Unity Mecanim 动画系统
1. Animator 组件 Controller:使用的Animator Controller文件. Avatar:使用的骨骼文件. Apply Root Motion:绑定该组件的GameObje ...
- 动态修改datagrid中的numberbox的最大值和最小值
注意datagrid使用的触发函数是: onBeginEdit,只有在这个触发条件下,editor才真正初始化完成,不然没法动态修改numberbox中的最大最小值. 示例代码:(注意这一块:onBe ...
- ServletContextListener中@Autowired失效的解决方法
@WebListener public class ContextWebListener implements ServletContextListener { @Override public vo ...
- 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 10—Advice for applying machine learning 机器学习应用建议
Lecture 10—Advice for applying machine learning 10.1 如何调试一个机器学习算法? 有多种方案: 1.获得更多训练数据:2.尝试更少特征:3.尝试更多 ...
- 在Ajax请求中什么时候用GET方式什么时候用POST方式?
当我们有大量数据要传送时最好的办法是一次发出多个只传递少量信息的Ajax调用时.如果你正用一个Ajax调用发送大量数据,那么最好是结束这种做法,因为这样做并不能节约时间. 因此,需要传送大量数据能成为 ...
- CMDB-客户端
配置文件的设置 大体思路: 1,通过开始文件将用户配置信息的文件放置到环境变量中. 2,在lib文件中的config文件中,从环境变量中获取到用户的配置,通过importlib模块导入用户配置文件,通 ...