Enumerable.Count() / Sum() / Average()
| Since: | C# 3.0(2007) |
|---|
LINQ extension methods for aggregating the count, sum, average, maximum, and minimum of a sequence.
Syntax
using System.Linq; int count = source.Count(); int count2 = source.Count(x => condition); long longCnt = source.LongCount(); int sum = source.Sum(); double avg = source.Average(); T max = source.Max(); T min = source.Min(); // You can also pass a selector to aggregate transformed values. int sumKey = source.Sum(x => x.Price); double avgKey = source.Average(x => x.Score);
Method List
| Method | Description |
|---|---|
| Count() | Returns the number of elements in the sequence. |
| Count(predicate) | Returns the number of elements that match the condition. |
| LongCount() | Returns the element count as a long (for large data sets). |
| Sum(selector) | Returns the sum of numeric elements (or transformed values). |
| Average(selector) | Returns the average of numeric elements. Throws an exception if the sequence is empty. |
| Max() | Returns the maximum value. |
| Max(selector) | Returns the maximum of the transformed values. |
| Min() | Returns the minimum value. |
| Min(selector) | Returns the minimum of the transformed values. |
| MaxBy(keySelector) | .NET 6 and later. Returns the element with the largest key. |
| MinBy(keySelector) | .NET 6 and later. Returns the element with the smallest key. |
Sample Code
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
List<int> scores = new List<int> { 80, 95, 70, 88, 60, 92 };
// Basic aggregation
Console.WriteLine(scores.Count()); // 6
Console.WriteLine(scores.Sum()); // 485
Console.WriteLine(scores.Average()); // 80.833...
Console.WriteLine(scores.Max()); // 95
Console.WriteLine(scores.Min()); // 60
// Conditional count (number of scores >= 80)
Console.WriteLine(scores.Count(s => s >= 80)); // 4
// Aggregate a list of objects using a selector.
var products = new List<(string Name, int Price, int Qty)>
{
("Apple", 150, 3),
("Orange", 80, 5),
("Banana", 120, 2),
};
Console.WriteLine(products.Sum(p => p.Price * p.Qty)); // 1090 — total sales
Console.WriteLine(products.Average(p => p.Price)); // 116.666... — average price
Console.WriteLine(products.Max(p => p.Price)); // 150 — highest price
var mostExpensive = products.MaxBy(p => p.Price);
Console.WriteLine(mostExpensive.Name); // Apple
// Aggregate by group.
var grouped = scores.GroupBy(s => s >= 80 ? "Pass" : "Fail");
foreach (var g in grouped)
Console.WriteLine($"{g.Key}: {g.Count()} students, average {g.Average():F1}");
Run the following command:
dotnet run 6 485 80.8333333333333 95 60 4 1090 116.666666666667 150 Apple Pass: 4 students, average 88.8 Fail: 2 students, average 65.0
Common Mistakes
Common Mistake: Calling Average() on an Empty Sequence Throws an Exception
Calling Average() on an empty sequence throws an InvalidOperationException. If the sequence may be empty, check with Any() first or use DefaultIfEmpty() to insert a fallback value.
using System; using System.Collections.Generic; using System.Linq; // NG: calling Average() on an empty sequence List<int> empty = new List<int>(); // double avg = empty.Average(); // InvalidOperationException: Sequence contains no elements.
The same logic can also be written as:
using System; using System.Collections.Generic; using System.Linq; // OK: check with Any() before calling Average() List<int> empty = new List<int>(); double avg1 = empty.Any() ? empty.Average() : 0.0; Console.WriteLine(avg1); // 0 // OK: insert a default value with DefaultIfEmpty() before averaging double avg2 = empty.DefaultIfEmpty(0).Average(); Console.WriteLine(avg2); // 0
Run the following command:
dotnet run 0 0
Notes
Methods such as Sum() and Average() use immediate evaluation — they traverse the entire sequence as soon as they are called. Calling them one after another causes multiple traversals, so for large data sets it is more efficient to materialize the sequence into a list first.
Average() throws an InvalidOperationException if the sequence is empty. If the sequence may be empty, check with Any() beforehand or combine it with DefaultIfEmpty().
If you only need to check whether any element matches a condition, Enumerable.Any(predicate) is more efficient than Count(predicate) > 0. To aggregate by group, combine these methods with Enumerable.GroupBy().
If you find any errors or copyright issues, please contact us.