Linq:执行链查询的顺序

Dej*_*jan 7 c# linq ienumerable ienumerator

我想了解如何处理链查询.例如,让我们考虑以下查询

var sumOfRoots = numbers           //IEnum0
     .Where(x => x > 0)            //IEnum1
     .Select(x => Math.Sqrt(x))    //IEnum2
     .Select(x => Math.Exp(x))     //IEnum3
     .Sum();
Run Code Online (Sandbox Code Playgroud)

例如 numbers={-1, 4, 9 }.

这是幕后发生的事情:

1.获得所有普查员(正面通行证)

  • numbers调用GetEnumerator()返回(让我们用它来表示)IEnum0实例
  • IEnum0GetEnumerator()返回IEnum1实例的调用
  • IEnum1GetEnumerator()返回IEnum2实例的调用
  • IEnum2GetEnumerator()返回IEnum3实例的调用

2.调用MoveNext(向后传递)

  • .Sum()呼吁MoveNext()IEnum3
  • IEnum3呼吁MoveNext()IEnum2
  • IEnum2呼吁MoveNext()IEnum1
  • IEnum1呼吁MoveNext()IEnum0

3.从MoveNext返回(前后传球)

  • IEnum0移动到元素-1并返回true.
  • IEnum1检查是否-1满足条件(这是不正确的),所以IEnum1要求MoveNext()IEnum0.
  • IEnum0移动到元素4并返回true.
  • IEnum1检查是否4满足条件(这是真的)并返回true
  • IEnum2什么也不做,只是返回的输出IEnum1true
  • IEnum2什么也不做,只是返回的输出IEnum2true

4.呼叫当前(向后传球)

  • .Sum()电话CurrentIEnum3.
  • IEnum3呼吁CurrentIEnum2
  • IEnum2呼吁CurrentIEnum1
  • IEnum1呼吁CurrentIEnum0

5.回流(前进传球)

  • IEnum0 回报 4
  • IEnum1 回报 4
  • IEnum2 回报 sqrt(4)=2
  • IEnum3 回报 exp(2)

6.重复步骤2.-5.直到第3步返回false

如果链接查询以不同的方式处理,请更正我.

Rui*_*mba 9

您可以使用委托来了解执行顺序.例:

static void Main(string[] args)
{
    var numbers = new []{ -1, 4, 9 };

    double sumOfRoots = numbers.Where(IsGreaterThanZero)   
                               .Select(ToSquareRoot)      
                               .Select(ToExp)              
                               .Sum(x => ToNumber(x));

    Console.WriteLine($"sumOfRoots = {sumOfRoots}");

    Console.Read();
}

private static double ToNumber(double number)
{
    Console.WriteLine($"SumNumber({number})");

    return number;
}

private static double ToSquareRoot(int number)
{
    double value =  Math.Sqrt(number);

    Console.WriteLine($"Math.Sqrt({number}): {value}");

    return value;
}

private static double ToExp(double number)
{
    double value =  Math.Exp(number);

    Console.WriteLine($"Math.Exp({number}): {value}");

    return value;
}

private static bool IsGreaterThanZero(int number)
{
    bool isGreater = number > 0;

    Console.WriteLine($"{number} > 0: {isGreater}");

    return isGreater;
}
Run Code Online (Sandbox Code Playgroud)

输出:

-1> 0:错误

4> 0:是的

Math.Sqrt(4):2

Math.Exp(2):7.38905609893065

SumNumber(7.38905609893065)

9> 0:是的

Math.Sqrt(9):3

Math.Exp(3):20.0855369231877

SumNumber(20.0855369231877)

sumOfRoots = 27.4745930221183