Syntax
collection.Sum() / .Count() / .Average() / .Max() / .Min()Examples
Basic Aggregations
The most common summary operations.
List<int> scores = new List<int> { 85, 92, 78, 90, 88 };
Console.WriteLine(scores.Count()); // 5
Console.WriteLine(scores.Sum()); // 433
Console.WriteLine(scores.Average()); // 86.6
Console.WriteLine(scores.Max()); // 92
Console.WriteLine(scores.Min()); // 78Aggregating with a Selector
Most aggregation methods accept a selector, letting you aggregate a property of complex objects directly.
record Product(string Name, double Price);
List<Product> cart = new List<Product>
{
new Product("Keyboard", 25),
new Product("Mouse", 15),
new Product("Monitor", 200)
};
double total = cart.Sum(p => p.Price);
Console.WriteLine(total); // 240
Product mostExpensive = cart.MaxBy(p => p.Price)!;
Console.WriteLine(mostExpensive.Name); // MonitorAggregate(): Custom Accumulation
The general-purpose reduction method for logic the built-in aggregators don't directly cover.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
int product = numbers.Aggregate(1, (acc, n) => acc * n);
Console.WriteLine(product); // 120
string combined = numbers.Aggregate("", (acc, n) => acc + n + "-");
Console.WriteLine(combined); // 1-2-3-4-5-Counting with a Condition
Count() can accept a predicate directly, avoiding a separate Where() step.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8 };
int evenCount = numbers.Count(n => n % 2 == 0);
Console.WriteLine(evenCount); // 4Best practices
- Use the selector overload (Sum(x => x.Property)) directly rather than chaining a separate Select() first - it is more concise and avoids an intermediate sequence
- Use Count(predicate) instead of Where(predicate).Count() to skip creating an intermediate filtered sequence
- Reach for Aggregate() only when the built-in Sum/Count/Average/Max/Min genuinely don't cover your accumulation logic - it is less readable for simple cases
- Handle empty sequences carefully - Average(), Max(), and Min() throw an exception on an empty sequence, so check .Any() first or use the null-returning "OrDefault" variants where available
At a glance
- Purpose
- Applications on the .NET platform
- File extension
- .cs
- Runs in
- .NET runtime
- Usually used with
- .NET SDK and libraries
Specifications & further reading
Related C# documentation
Lambda Expressions
A lambda expression is a compact way to represent an anonymous function - a block of code that can be passed around as a value, using the => (goes to) operator. Lambdas work with delegate types and functional interfaces like Func<> and Action<>, letting you write inline logic without a full named method. Lambdas are the foundation that makes LINQ's fluent, expressive query syntax possible.LINQ Basics: Where & Select
LINQ (Language Integrated Query) provides a consistent, declarative way to query collections, databases, and XML directly within C# syntax. Where() filters a sequence down to elements matching a condition, and Select() transforms each element into something new (a projection). Both are 'lazy' - they build a query that only actually runs when you iterate over the result or call something like ToList().LINQ Ordering & Grouping
OrderBy() and OrderByDescending() sort a sequence by a key you specify, with ThenBy() for secondary sort keys on ties. GroupBy() splits a sequence into groups based on a key selector, producing a sequence of groups where each group itself is enumerable and has a Key property identifying which group it represents.LINQ Element & Quantifier Operators
Element operators retrieve a single item from a sequence: First()/FirstOrDefault() for the first match, Single()/SingleOrDefault() for exactly one match, with 'OrDefault' variants returning a default value instead of throwing when nothing matches. Quantifier operators return a bool describing the sequence as a whole: Any() checks if at least one element matches, and All() checks if every element matches.
A lambda expression is a compact way to represent an anonymous function - a block of code that can be passed around as a value, using the => (goes to) operator. Lambdas work with delegate types and functional interfaces like Func<> and Action<>, letting you write inline logic without a full named method. Lambdas are the foundation that makes LINQ's fluent, expressive query syntax possible.LINQ Basics: Where & Select
LINQ (Language Integrated Query) provides a consistent, declarative way to query collections, databases, and XML directly within C# syntax. Where() filters a sequence down to elements matching a condition, and Select() transforms each element into something new (a projection). Both are 'lazy' - they build a query that only actually runs when you iterate over the result or call something like ToList().LINQ Ordering & Grouping
OrderBy() and OrderByDescending() sort a sequence by a key you specify, with ThenBy() for secondary sort keys on ties. GroupBy() splits a sequence into groups based on a key selector, producing a sequence of groups where each group itself is enumerable and has a Key property identifying which group it represents.LINQ Element & Quantifier Operators
Element operators retrieve a single item from a sequence: First()/FirstOrDefault() for the first match, Single()/SingleOrDefault() for exactly one match, with 'OrDefault' variants returning a default value instead of throwing when nothing matches. Quantifier operators return a bool describing the sequence as a whole: Any() checks if at least one element matches, and All() checks if every element matches.