我想了解如何处理链式查询。例如,让我们考虑以下查询
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。呼叫当前(向后传递)
.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
如果以不同方式处理链式查询,请纠正我。
答案 0 :(得分: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;
}
输出:
-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