• 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

  • 相关阅读:
    SPOJ SAMER08A
    SPOJ TRAFFICN
    CS Academy Set Subtraction
    CS Academy Bad Triplet
    CF Round 432 C. Five Dimensional Points
    CF Round 432 B. Arpa and an exam about geometry
    SPOJ INVCNT
    CS Academy Palindromic Tree
    身体训练
    简单瞎搞题
  • 原文地址:https://www.cnblogs.com/dragon-L/p/6481277.html
Copyright © 2020-2023  润新知