zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    在CentOS中安装VMware Tools
    引用
    iomanip头文件库函数
    第2章 寄存器(CPU工作原理)
    二维差分
    组合数学——康托展开和逆康托展开
    动态规划精讲(一)区域和检索
    动态规划精讲(一)最大子矩阵
    freopen
    动态规划精讲(一)环形子组数的最大和
  • 原文地址:https://www.cnblogs.com/dragon-L/p/6481277.html
Copyright © 2011-2022 走看看