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源码分析的更多相关文章

  1. Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析

    Linq转换操作之OfType,Cast,AsEnumerable,ToLookup源码分析 一:Tolookup 1. 从方法的注解上可以看到,ToLookup也是一个k,v的形式,那么问题来了,它 ...

  2. Linq分组操作之GroupBy,GroupJoin扩展方法源码分析

    Linq分组操作之GroupBy,GroupJoin扩展方法源码分析 一. GroupBy 解释: 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值. 查询表达式: var ...

  3. Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析

    Linq聚合操作之Aggregate,Count,Sum,Distinct源码分析 一:Linq的聚合运算 1. 常见的聚合运算:Aggregate,Count, Sum, Distinct,Max, ...

  4. Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析

    Linq生成操作之DefautIfEmpty,Empty,Range,Repeat源码分析 Linq的四种生成运算 DefautIfEmpty,Empty,Range,Repeat 也就是给我们初始化 ...

  5. Linq特取操作之ElementAt,Single,Last,First源码分析

    Linq特取操作之ElementAt,Single,Last,First源码分析 一:linq的特取操作 First/FirstOrDefault, Last/LastOrDefault, Eleme ...

  6. Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析

    Linq扩展最后遗留之SelectMany,Zip,SequenceEqual源码分析 一: AsParallel [并行化查询] 这个函数的功效就是将计算结果多线程化.[并行计算] =>[多核 ...

  7. Java基础系列--07_Object类的学习及源码分析

    Object: 超类 (1)Object是类层次结构的顶层类,是所有类的根类,超类.   所有的类都直接或者间接的继承自Object类.   所有对象(包括数组)都实现这个类的方法 (2)Object ...

  8. 第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+ ...

  9. Linq集合操作之Intersect,Except,Union源码分析

    Linq集合操作之Intersect,Except,Union源码分析 linq的集合运算 常见的集合运算有哪些? 这三个扩展方法在我们实际使用中用的还是非常多的,而且这里还涉及到了“复杂度” 无算法 ...

随机推荐

  1. angularjs之级联菜单

    原理: 1.ng-options中val.id as val.name for val in cascading 将id的值赋给 mg-modelone2.在通过ng-change传给函数3.当一级下 ...

  2. PDO execute 执行错误

    PHP   PDO execute 执行错误,原因分析 $dbcon->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);或者 $db ...

  3. objective-C中的"非正式协议"和“正式协议”

    objective-C中的接口与泛型 先承认我是标题党,因为在obj-c的世界中,官方根本没有"接口"与"泛型"这样的说法. 不过在obj-c中有二个与之接近的 ...

  4. visjs使用小记-1.创建一个简单的网络拓扑图

    1.插件官网:http://visjs.org/ 2.创建一个简单的网络拓扑图 <!doctype html> <html> <head> <title> ...

  5. PHP 数组中出现中文乱码,json_encode返回结果为null 或false

    想要解决这个问题,没有特别方便的方法,只有循环数组,将数组中的key和value字符串转码,转换为utf-8,即可解决问题. 代码示例:

  6. 全文搜索技术—Lucene

    1.   内容安排 实现一个文件的搜索功能,通过关键字搜索文件,凡是文件名或文件内容包括关键字的文件都需要找出来.还可以根据中文词语进程查询,并且支持多种条件查询. 本案例中的原始内容就是磁盘上的文件 ...

  7. 【BZOJ3998】弦论 【后缀自动机】

    题意 给定一个长度为n的字符串,求他的第k小子串是什么. 分析 T=0的时候,这个题跟SPOJ-SUBLEX的做法一样,当T=1的时候,不同位置的子串算多个,那么初始化的时候d[u]=cnt[u],没 ...

  8. Codeforces 1154G 枚举

    题意:给你一堆数,问其中lcm最小的一对数是什么? 思路:因为lcm(a, b) = a * b / gcd(a, b), 所以我们可以考虑暴力枚举gcd, 然后只找最小的a和b,去更新答案即可. 数 ...

  9. 虚拟机硬盘格式的选择:qcow2、 raw等

    虚拟机硬盘格式的选择:qcow2. raw等曾经有过一段时间,徘徊于对虚拟机硬盘格式的迷惑中,2009年,终于得出了一些结论(下面的思路基本通用于其他虚拟机) 搜了下,发现大部分用qemu或者kvm的 ...

  10. Redhat Cluster Suite原理介绍

      RedHat Cluster Suite简称RHCS,是一个能够提供高可用性.高可靠性.负载均衡.存储共享且经济廉价的集群工具集合,基于RHCS可以搭建高可用性集群.负载均衡集群.存储集群和高性能 ...