我想了解链式查询是如何处理的。例如,让我们考虑以下查询
var sumOfRoots = numbers //IEnum0
.Where(x => x > 0) //IEnum1
.Select(x => Math.Sqrt(x)) //IEnum2
.Select(x => Math.Exp(x)) //IEnum3
.Sum();
例如,
numbers={-1, 4, 9 }.
这就是幕后发生的事情吗:
1。获取所有枚举器(前向传递)
numbers
调用 GetEnumerator()
并返回(让我们用它表示) IEnum0
实例IEnum0
调用 GetEnumerator()
返回 IEnum1
实例IEnum1
调用 GetEnumerator()
返回 IEnum2
实例IEnum2
调用 GetEnumerator()
返回 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
什么都不做,只是返回 IEnum1
的输出,即 true
IEnum2
什么都不做,只是返回 IEnum2
的输出,即 true
4。调用Current(向后传递)
.Sum()
在 Current
上呼叫 IEnum3
。IEnum3
致电 Current
IEnum2
IEnum2
致电 Current
IEnum1
IEnum1
致电 Current
IEnum0
5。返回电流(正向传递)
IEnum0
返回4
IEnum1
返回4
IEnum2
返回sqrt(4)=2
IEnum3
返回exp(2)
6。重复步骤 2.-5。直到第 3 步返回 false
如果链查询以不同的方式处理,请纠正我。
您可以使用委托来了解执行顺序。示例:
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;
}
输出:
-1 > 0: False
4 > 0: True
Math.Sqrt(4): 2
Math.Exp(2): 7.38905609893065
SumNumber(7.38905609893065)
9 > 0: True
Math.Sqrt(9): 3
Math.Exp(3): 20.0855369231877
SumNumber(20.0855369231877)
sumOfRoots = 27.4745930221183