Enumerable.Aggregate()
| Since: | C# 3.0(2007) |
|---|
A LINQ extension method that accumulates a sequence from left to right into a single value. It is equivalent to reduce in other languages. An accumulator is a variable that accumulates the result of each step in a loop. Use Aggregate() when you need custom aggregation logic that cannot be expressed with Sum() or Max() alone.
Syntax
using System.Linq; // Accumulates the sequence without a seed value — the first element acts as the initial accumulator. T result = source.Aggregate((acc, x) => accumulator expression); // Accumulates the sequence with a specified seed value. TAccumulate result = source.Aggregate(seed, (acc, x) => accumulator expression); // Accumulates the sequence and then transforms the result. TResult result = source.Aggregate(seed, (acc, x) => accumulator expression, acc => result selector);
Method List
| Signature | Description |
|---|---|
| Aggregate(func) | No seed value. Uses the first element as the initial accumulator. Throws an exception for an empty sequence. |
| Aggregate(seed, func) | Accumulates with a specified seed value. Safe to use with an empty sequence. |
| Aggregate(seed, func, resultSelector) | Accumulates and then transforms the accumulator before returning it. |
Sample Code
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Calculate the product of all elements (1×2×3×4×5).
int product = numbers.Aggregate((acc, n) => acc * n);
Console.WriteLine(product); // 120
// Calculate the sum with a seed value (equivalent to Sum()).
int sum = numbers.Aggregate(0, (acc, n) => acc + n);
Console.WriteLine(sum); // 15
// Concatenate strings with a seed value.
List<string> words = new List<string> { "Hello", "World", "LINQ" };
string joined = words.Aggregate("", (acc, w) => acc == "" ? w : acc + ", " + w);
Console.WriteLine(joined); // Hello, World, LINQ
// Find the maximum value using Aggregate (in practice, use Max() instead).
int max = numbers.Aggregate((acc, n) => acc > n ? acc : n);
Console.WriteLine(max); // 5
// Overload that transforms the result: calculate the sum and convert it to a string.
string result = numbers.Aggregate(
0,
(acc, n) => acc + n,
acc => $"Total is {acc}"
);
Console.WriteLine(result); // Total is 15
// Count the total number of characters in a list of strings.
int totalLen = words.Aggregate(0, (acc, w) => acc + w.Length);
Console.WriteLine(totalLen); // 14
Run the following command:
dotnet run 120 15 Hello, World, LINQ 5 Total is 15 14
Common Mistakes
Common Mistake: Aggregate() Without a Seed Throws on an Empty Sequence
When no seed value is provided, Aggregate() uses the first element of the sequence as the initial accumulator. If the sequence is empty, there is no first element, so an InvalidOperationException is thrown. Always use the overload with a seed value when the sequence may be empty.
using System; using System.Collections.Generic; using System.Linq; // NG: Aggregate() without a seed on an empty sequence List<int> empty = new List<int>(); // int result = empty.Aggregate((acc, n) => acc + n); // InvalidOperationException
The same logic can also be written as:
using System;
using System.Collections.Generic;
using System.Linq;
// OK: use the overload with a seed value
List<int> empty = new List<int>();
int result = empty.Aggregate(0, (acc, n) => acc + n);
Console.WriteLine(result); // 0 (safe even when empty)
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
int sum = numbers.Aggregate(0, (acc, n) => acc + n);
Console.WriteLine(sum); // 15
Run the following command:
dotnet run 0 15
Notes
Aggregate() is a general-purpose accumulation method. For common aggregations such as sums or maximums, dedicated methods like Sum() and Max() are more readable. However, Aggregate() shines when you need complex custom aggregation logic.
Calling Aggregate() without a seed value on an empty sequence throws an InvalidOperationException. If the sequence may be empty, always use the overload that accepts a seed value.
For common aggregations such as sums, averages, and counts, dedicated methods are more efficient. See Enumerable.Count() / Sum() / Average() for details.
If you find any errors or copyright issues, please contact us.