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. Mellanox infinoband RDMA SDP

    IPoIB Internet Protocol over InfiniBand 就是指利用物理IB网络(IB卡,线缆,交换机,更甚者IB3层交换)通过ip协议进行连接,并进行数据传输! SDP Soc ...

  2. pandas入门学习--------------------------(一)

    使用pandas,首先需要熟悉它的2个主要的数据结构:Series和DataFrame. Series series是一种类似于一维数组的的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关 ...

  3. 1、svn架设、基本命令

    SVN是Subversion的简称,是一个开放源代码的版本控制系统.是一项十分基础,必须能够熟练使用的工具.Apache网站:https://subversion.apache.org/ 采用C/S模 ...

  4. leetcode442

    public class Solution { Dictionary<int, int> dic = new Dictionary<int, int>(); public IL ...

  5. Please specify exact device preset UUID

    Please specify exact device preset UUID 重启RAD IDE,重新选择 IOS Simulator ,iphone 机型!

  6. 前端Blob对象的使用

    最近移动端界面给后台传数据时用到Blob,它可以看做是存放二进制数据的容器: //上传图片数据封装 function uploadPhotoData(data,fileName){ var imgAr ...

  7. UVALIVE 4556 The Next Permutation

    4556 The Next PermutationFor this problem, you will write a program that takes a (possibly long) str ...

  8. UNITY 内存问题资料收集

    1,https://blog.csdn.net/wetest_tencent/article/details/52130703 2,http://blog.51cto.com/13638120/208 ...

  9. 利用Fiddler对Android模拟器网络请求进行抓包

    安装使用Fiddler 下载安装Fiddler的方法这里就略过了,一路Next就行了.装好之后运行软件,正常情况这个时候我们已经可以对电脑的网络请求进行抓包了.Fiddler默认的代理地址是127.0 ...

  10. SEL 类型

    1.SEL类型的第一个作用, 配合对象/类来检查对象/类中有没有实现某一个方法 SEL sel = @selector(setAge:); Person *p = [Person new]; // 判 ...