我不理解以下代码中的执行顺序。这里满足第一个Where
子句的数字是(4,10,3,7),满足第二个Where
子句的数字是2和1,之后我们有了函数{{1 }}减去它们并从两者中选出一个。
我的问题是,这里的执行流程是-(1)对所有元素使用c / 3> 0执行Aggregate
,然后执行(2)Where
或(1)首先子句是针对一个元素执行的,并将其传递给(2)并从那里进行聚合-当我打印值时,两种方法都无法使x的值在纸上等于28,也无法调试linq语句。感谢您的任何提前帮助。
Where
答案 0 :(得分:6)
同一条语句可以编写如下:
var ints = new int[] { 2, 4, 1, 10, 3, 7 };
var x = ints
.Where(c =>
{
Console.WriteLine($"1 Where for number: {c}");
return c / 3 > 0;
}) //< --(1)
.Select(s2 => s2 + ints
.Where(c =>
{
Console.WriteLine($"2 Where for number: {c}");
return c / 3 == 0;
}) // < --(2)
.Aggregate((f, s) =>
{
Console.WriteLine($"Aggregate: f: {f} s: {s}");
return f - s;
}))
.Sum();
在此,每个速记lambda表达式都可以编写为带有方法主体的完整匿名方法。您只需要使用{ .. }
括号即可。在其中可以编写多个语句。如果查看Where的文档,您会发现它期望Func<int, bool>
作为输入参数。这意味着您在内部传递了int
,并返回了bool
。这就是为什么您需要像我一样编写显式return语句的原因:return c / 3 > 0;
如果您现在在控制台中插入调试输出,您将获得书面证明并深入了解整个代码仓的执行情况。
结果输出如下:
1 Where for number: 2 1 Where for number: 4 2 Where for number: 2 2 Where for number: 4 2 Where for number: 1 Aggregate: f: 2 s: 1 2 Where for number: 10 2 Where for number: 3 2 Where for number: 7 1 Where for number: 1 1 Where for number: 10 2 Where for number: 2 2 Where for number: 4 2 Where for number: 1 Aggregate: f: 2 s: 1 2 Where for number: 10 2 Where for number: 3 2 Where for number: 7 1 Where for number: 3 2 Where for number: 2 2 Where for number: 4 2 Where for number: 1 Aggregate: f: 2 s: 1 2 Where for number: 10 .... ....
答案 1 :(得分:4)
ints
.Where(c => c / 3 == 0) // (2,1)
.Aggregate((f, s) => f - s) // 2-1
评估为1
因此您的查询可以切换到:
var ints = new int[] { 2, 4, 1, 10, 3, 7 };
var x = ints
.Where(c => c / 3 > 0) // (4,10,3,7)
.Select(s2 => s2 + 1) // (5,11,4,8)
.Sum(); // 28