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

  • 相关阅读:
    那些创业的艰辛整理
    一个成功的研发团队应具备的9大属性
    如何将 Linux 系统转移至 LVM 卷
    如何在 Linux 上永久挂载一个 Windows 共享
    怎样在 Chromebook 上安装 Linux 系统?
    1087 有多少不同的值 (20 分)C语言
    1052 卖个萌 (20 分)C语言
    1064 朋友数 (20 分)C语言
    1045 快速排序 (25 分)C语言
    1048 数字加密 (20 分)C语言
  • 原文地址:https://www.cnblogs.com/dragon-L/p/6481277.html
Copyright © 2011-2022 走看看