LINQ aggregate methods in C# — Sum, Count, Average, Min, Max, Aggregate

LINQ aggregate methods reduce a sequence down to a single value. They are the C# equivalent of SQL's SUM, COUNT, AVG, MIN, and MAX functions.

All aggregate methods execute immediately — they do not use deferred execution.

Sum

C# Example Code
var numbers = new List<int> { 1, 2, 3, 4, 5 };

int total = numbers.Sum();
Console.WriteLine(total); // 15

// Sum a property of each object
var products = new List<Product>
{
    new Product("Laptop", 999.99m),
    new Product("Mouse",   29.99m),
    new Product("Keyboard", 79.99m)
};

decimal grandTotal = products.Sum(p => p.Price);
Console.WriteLine(grandTotal); // 1109.97

record Product(string Name, decimal Price);

Count

C# Example Code
var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

// Total count
int total = numbers.Count();
Console.WriteLine(total); // 6

// Count with a predicate
int evenCount = numbers.Count(n => n % 2 == 0);
Console.WriteLine(evenCount); // 3

// LongCount for very large sequences
long bigCount = numbers.LongCount();

Average

C# Example Code
var scores = new List<double> { 88.0, 92.5, 76.0, 95.5, 84.0 };

double avg = scores.Average();
Console.WriteLine(avg); // 87.2

// Average of a property
var employees = new List<Employee>
{
    new Employee("Alice", 75_000),
    new Employee("Bob",   85_000),
    new Employee("Carol", 95_000)
};

double avgSalary = employees.Average(e => e.Salary);
Console.WriteLine(avgSalary); // 85000

record Employee(string Name, int Salary);

Min and Max

C# Example Code
var temperatures = new List<double> { 22.1, 18.5, 30.0, 25.3, 15.8 };

double min = temperatures.Min();
double max = temperatures.Max();

Console.WriteLine($"Min: {min}, Max: {max}"); // Min: 15.8, Max: 30

// Min/Max on object property
var products = new List<Product>
{
    new Product("Laptop",   999.99m),
    new Product("Mouse",     29.99m),
    new Product("Keyboard",  79.99m)
};

decimal cheapest = products.Min(p => p.Price);
decimal mostExpensive = products.Max(p => p.Price);

Console.WriteLine($"Cheapest: {cheapest}, Most expensive: {mostExpensive}");
// Cheapest: 29.99, Most expensive: 999.99

record Product(string Name, decimal Price);

MinBy and MaxBy (C# 10 / .NET 6+)

MinBy() and MaxBy() return the object with the minimum or maximum key, not just the value.

C# Example Code
var products = new List<Product>
{
    new Product("Laptop",   999.99m),
    new Product("Mouse",     29.99m),
    new Product("Keyboard",  79.99m)
};

Product? cheapest    = products.MinBy(p => p.Price);
Product? mostExpensive = products.MaxBy(p => p.Price);

Console.WriteLine(cheapest?.Name);     // Mouse
Console.WriteLine(mostExpensive?.Name); // Laptop

record Product(string Name, decimal Price);

Aggregate — Custom Reduction

Aggregate() is the general-purpose fold operation. It applies a function to each element, threading an accumulator through the sequence.

C# Example Code
var numbers = new List<int> { 1, 2, 3, 4, 5 };

// Running product: 1 * 2 * 3 * 4 * 5 = 120
int product = numbers.Aggregate((acc, n) => acc * n);
Console.WriteLine(product); // 120

// With a seed value (starting accumulator)
int sumPlusTen = numbers.Aggregate(10, (acc, n) => acc + n);
Console.WriteLine(sumPlusTen); // 25 (10 + 1+2+3+4+5)

Aggregate with a Result Selector

C# Example Code
var words = new List<string> { "hello", "world", "from", "csharp" };

// Build a sentence, then transform the result
string sentence = words.Aggregate(
    seed: new System.Text.StringBuilder(),
    func: (sb, word) => sb.Append(sb.Length > 0 ? " " : "").Append(word),
    resultSelector: sb => sb.ToString().ToUpper()
);

Console.WriteLine(sentence); // HELLO WORLD FROM CSHARP

Combining Aggregates with GroupBy

C# Example Code
var orders = new List<Order>
{
    new Order("Alice", "Electronics", 499.00m),
    new Order("Bob",   "Books",        19.99m),
    new Order("Alice", "Books",        12.50m),
    new Order("Bob",   "Electronics", 299.00m),
    new Order("Carol", "Electronics", 899.00m)
};

// Total revenue per category
var revenueByCategory = orders
    .GroupBy(o => o.Category)
    .Select(g => new
    {
        Category = g.Key,
        Total    = g.Sum(o => o.Amount),
        Count    = g.Count(),
        Average  = g.Average(o => o.Amount)
    })
    .OrderByDescending(x => x.Total);

foreach (var r in revenueByCategory)
    Console.WriteLine($"{r.Category}: total={r.Total:C}, count={r.Count}, avg={r.Average:C}");

// Electronics: total=$1,697.00, count=3, avg=$565.67
// Books:       total=$32.49,   count=2, avg=$16.25

record Order(string Customer, string Category, decimal Amount);

Null-Safe Aggregates

Aggregate methods on an empty sequence throw InvalidOperationException. Guard with a null-conditional or DefaultIfEmpty().

C# Example Code
var empty = new List<int>();

// Throws InvalidOperationException:
// int bad = empty.Sum(); // safe — Sum returns 0 for empty
// int bad = empty.Max(); // throws!

// Safe alternatives:
int safeMax   = empty.DefaultIfEmpty(0).Max(); // 0
int? nullMax  = empty.Any() ? empty.Max() : (int?)null;

Console.WriteLine(safeMax);  // 0
Console.WriteLine(nullMax);  // (blank — null)

Quick Reference

MethodReturnsThrows on empty?
Sum()Numeric totalNo — returns 0
Count()Element countNo — returns 0
Average()Arithmetic meanYes
Min()Smallest valueYes
Max()Largest valueYes
MinBy()Object with smallest keyYes
MaxBy()Object with largest keyYes
Aggregate(func)Folded resultYes (no seed)
Aggregate(seed, func)Folded resultNo