Linq中Sum()的几种语法差异

本文关键字:几种 语法 Sum Linq | 更新日期: 2023-09-27 18:06:17

linq中方法Sum的这三次调用有什么区别?

decimal Sum1 = Shops.Sum(x => x.Amount);
decimal Sum2 = Shops.Select(x => x.Amount).Sum();
decimal Sum3 = Shops.Select(x => x).Sum(x => x.Amount);

Linq中Sum()的几种语法差异

上述三种方法之间存在细微的差异,尽管根据当前调用每种方法的方式,它们应该产生相同的数量。

decimal Sum1 = Shops.Sum(x => x.Amount);使用Func过载来标识要对源集合求和的属性,并在内部遍历源时使用。

decimal Sum2 = Shops.Select(x => x.Amount).Sum();创建一个新的IEnumerable<T>投影,然后将其传递给.Sum()扩展方法并在内部迭代和求和。

decimal Sum3 = Shops.Select(x => x).Sum(x => x.Amount);除了(潜在地)造成额外的开销和混乱之外没有任何作用,因为它与第一个示例相同,同时允许您在此过程中创建新的投影。

最终金额没有差别。

区别在于表达式树的组成。这些都是相似的,但执行方式不同,因为表达式树的构建方式不同。

LINQ适用于延迟执行。在这种情况下,它被延迟到调用Sum。延迟执行通常通过枚举一个可枚举对象来工作。构建的可枚举对象在每种情况下都是不同的。

  • Shops.Sum(x => x.Amount);
    在这个场景中,Enumerable已经被构建,它是Shops。对Sum的调用枚举Shops可枚举对象,并为每个元素添加x.Amount的值。

  • Shops.Select(x => x.Amount).Sum();
    在这个场景中,正在构建的Enumerable是一个"投影"(Select)。投影将只从每个Shop元素中获取每个Amount。在这个可枚举对象上使用Sum,遍历每个单独的数量并将其相加。

  • Shops.Select(x => x).Sum(x => x.Amount);
    这个场景可以编译出来。Select(x => x)实际上并没有产生任何不同。因此,这很可能与第一种情况相同。