C#的LINQ提供了丰富的集合操作方法,其中Aggregate方法是实现累积聚合的核心工具,它可以将集合中的元素通过一个累加器函数逐步合并,最终得到一个单一的结果。除了基础的求和、求积场景,它还支持很多复杂的高级用法,能够满足多样化的数据处理需求。

Aggregate方法基础原理
Aggregate方法属于System.Linq命名空间下的扩展方法,它的核心逻辑是遍历集合,每次将当前元素和之前的累积结果传入指定的函数,更新累积结果,直到遍历完成返回最终结果。最基础的用法只需要传入一个累加函数,例如对整数集合求和:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 基础求和用法,初始累积值为第一个元素1,之后依次加2、3、4、5
int sum = numbers.Aggregate((current, next) => current + next);
Console.WriteLine($"集合求和结果:{sum}"); // 输出15
}
}
Aggregate的高级重载用法
1. 指定初始累积值
默认的Aggregate重载会使用集合的第一个元素作为初始累积值,如果需要自定义初始值,可以使用带seed参数的重载,该重载接收三个参数:初始累积值、累积函数、结果转换函数(可选)。例如从10开始累加集合元素:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 指定初始累积值为10,最终结果为10+1+2+3+4+5=25
int sumWithSeed = numbers.Aggregate(10, (current, next) => current + next);
Console.WriteLine($"带初始值的求和结果:{sumWithSeed}"); // 输出25
}
}
2. 结果转换
如果最终需要的不是累积值的原始类型,而是需要转换后的结果,可以使用三个参数的重载,第三个参数是结果转换函数。例如计算集合元素的乘积后转换为字符串:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4 };
// 初始值为1,累积乘积,最后将结果转换为字符串
string productStr = numbers.Aggregate(1, (current, next) => current * next, result => $"乘积结果为:{result}");
Console.WriteLine(productStr); // 输出乘积结果为:24
}
}
3. 复杂对象聚合
Aggregate不仅支持值类型的聚合,也支持复杂对象的聚合场景。例如有一个订单列表,需要聚合得到所有订单的总金额、总商品数量:
using System;
using System.Collections.Generic;
using System.Linq;
public class Order
{
public int OrderId { get; set; }
public decimal Amount { get; set; }
public int ProductCount { get; set; }
}
public class OrderSummary
{
public decimal TotalAmount { get; set; }
public int TotalProductCount { get; set; }
}
class Program
{
static void Main()
{
List<Order> orders = new List<Order>
{
new Order { OrderId = 1, Amount = 99.9m, ProductCount = 2 },
new Order { OrderId = 2, Amount = 199.8m, ProductCount = 3 },
new Order { OrderId = 3, Amount = 49.9m, ProductCount = 1 }
};
// 初始聚合对象,累积更新总金额和总商品数
OrderSummary summary = orders.Aggregate(
new OrderSummary { TotalAmount = 0, TotalProductCount = 0 },
(current, next) => new OrderSummary
{
TotalAmount = current.TotalAmount + next.Amount,
TotalProductCount = current.TotalProductCount + next.ProductCount
}
);
Console.WriteLine($"总订单金额:{summary.TotalAmount},总商品数量:{summary.TotalProductCount}");
// 输出总订单金额:349.6,总商品数量:6
}
}
使用注意事项
- 如果集合为空,使用无初始值的Aggregate重载会抛出InvalidOperationException,因此空集合场景建议使用带初始值的重载,或者在调用前判断集合是否为空。
- 累积函数的逻辑需要保证不会产生意外的副作用,例如修改外部变量,否则会导致结果不可预期。
- 如果聚合逻辑比较简单,也可以考虑使用Sum、Count等专用方法,可读性和性能会略优于Aggregate,复杂聚合场景再使用Aggregate更合适。
常见场景示例
例如需要将字符串集合拼接成用逗号分隔的字符串,就可以使用Aggregate实现:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<string> tags = new List<string> { "C#", "LINQ", "Aggregate", "教程" };
// 拼接字符串,初始值为空字符串,中间添加逗号分隔
string tagStr = tags.Aggregate("", (current, next) => string.IsNullOrEmpty(current) ? next : current + "," + next);
Console.WriteLine(tagStr); // 输出C#,LINQ,Aggregate,教程
}
}