Calculate the Average of Numbers in C# – The Complete Guide

Calculating an average (also known as the mean) sounds simple – but in C#, how you calculate it depends on:

  • what type of numbers you have,
  • where the numbers come from (arrays, lists, LINQ queries, streams),
  • whether you need rounding,
  • overflow protection,
  • high-precision decimal accuracy,
  • performance on large datasets.

This guide explains every way to compute averages in C#, from beginner basics to advanced numerical techniques used in finance, game dev, machine learning, and high-performance systems.


1. What Does “Average” Mean in Programming?

The average (arithmetic mean) is:

sum of all numbers ÷ count of numbers

Example:
Values = { 2, 4, 6, 8 }
Average = (2 + 4 + 6 + 8) / 4 = 5

Every method in this guide is based on that simple rule – only the implementation differs.


2. The Easiest Method: Using LINQ.Average()

⭐ Best for: beginners, readability, quick code

❌ Not ideal for: systems needing maximum performance

int[] numbers = { 2, 4, 6, 8 };

double avg = numbers.Average();

How it works internally:

  • Iterates once through the sequence
  • Computes the sum
  • Computes the count
  • Returns a double, even if input is integers
  • Throws InvalidOperationException if the sequence is empty

Why it’s great:

✔ 1 line
✔ Readable
✔ Works with any numeric type
✔ Works with projections (.Average(x => x.Price))


3. Full Manual Calculation (Best for Learning)

int[] nums = { 2, 4, 6, 8 };

double sum = 0;

for (int i = 0; i < nums.Length; i++)
{
    sum += nums[i];
}

double average = sum / nums.Length;

What this teaches:

  • How sums accumulate
  • Why we cast to double
  • Why sum is NOT an int
  • Dividing two integers does integer division (avoid!)

4. Avoiding Integer Division Bugs

If you do:

int avg = sum / count;

You will get integer division (truncates decimals):

int sum = 5;
int count = 2;
int avg = sum / count;  // 2, not 2.5

Fix it by casting:

double avg = (double)sum / count;

5. Handling Empty Collections Safely

LINQ version

double avg = numbers.Any() ? numbers.Average() : 0;

Manual version

if (numbers.Length == 0)
    return 0;

Choose your own “empty value” (0, null, nullable double, etc.).


6. Using decimal for Finance (HIGH Precision)

double is fast but has floating-point rounding issues.
If you’re doing:

  • currency
  • financial calculations
  • invoicing
  • VAT percentages

Use decimal.

decimal[] values = { 10.25m, 20.25m, 30.25m };

decimal avg = values.Average();

LINQ performs a decimal-aware average automatically.


7. Performance-Optimised Average (Large Datasets)

For millions of numbers, reduce allocations and improve CPU cache performance:

double AverageFast(int[] numbers)
{
    long sum = 0; // prevents overflow
    int count = numbers.Length;

    for (int i = 0; i < count; i++)
        sum += numbers[i];

    return (double)sum / count;
}

Why long sum?

  • Prevents overflow for large arrays
  • Still very fast
  • Avoids LINQ overhead

8. Using Span<T> for High-Performance Scenarios

double AverageSpan(ReadOnlySpan<int> span)
{
    long sum = 0;

    for (int i = 0; i < span.Length; i++)
        sum += span[i];

    return (double)sum / span.Length;
}

Why this is pro-level:

  • Span<T> avoids array-bound checking overhead
  • Zero heap allocations
  • Perfect for game loops / real-time processing

9. Averaging With LINQ Projections (Real World)

Objects

var people = new[]
{
    new { Name = "Eva", Age = 30 },
    new { Name = "Tom", Age = 40 },
    new { Name = "Sam", Age = 50 }
};

double avgAge = people.Average(p => p.Age);

Database rows

(When using Entity Framework, this becomes SQL AVG() automatically)

double avgPrice = db.Products.Average(p => p.Price);

10. Weighted Average (IMPORTANT for data science)

Not all items have equal importance.

Example: Test scores with weightings:

double WeightedAverage(int[] values, int[] weights)
{
    double sum = 0;
    double totalWeight = 0;

    for (int i = 0; i < values.Length; i++)
    {
        sum += values[i] * weights[i];
        totalWeight += weights[i];
    }

    return sum / totalWeight;
}

11. Streaming Average (Do NOT Load All Data)

Use this when you read numbers one by one from:

  • files
  • database streams
  • telemetry
  • IoT sensors
double sum = 0;
long count = 0;

foreach (var x in stream)
{
    sum += x;
    count++;
}

double avg = sum / count;

Why this matters:

  • No array needed
  • Memory usage stays tiny

12. Online Average (No Sum Overflow, Real Time)

This prevents overflow AND calculates average on the fly.

Formula (Welford’s Method):

double avg = 0;
long count = 0;

foreach (var value in values)
{
    count++;
    avg += (value - avg) / count;
}

Benefits:

✔ Best numerical stability
✔ Works with huge streams
✔ Never overflows
✔ Used in scientific computing


13. Using Aggregate() in LINQ (Functional Style)

double avg = numbers
    .Aggregate(
        new { Sum = 0.0, Count = 0 },
        (acc, x) => new { Sum = acc.Sum + x, Count = acc.Count + 1 },
        acc => acc.Sum / acc.Count
    );

Not beginner-friendly but extremely expressive.


14. Parallel Average (PLINQ)

For extremely large numbers:

double avg = numbers
    .AsParallel()
    .Average();

Useful when:

  • Millions of items
  • Multi-core CPU
  • Purely numeric data

15. Averaging Specific Parts of an Array

Average of first N items:

double avgFirst = numbers.Take(10).Average();

Average of last N items:

double avgLast = numbers.Skip(numbers.Length - 10).Average();

Average of even numbers only:

double avgEven = numbers.Where(n => n % 2 == 0).Average();

16. Rounding the Average

Round to 2 decimals:

double rounded = Math.Round(avg, 2);

Round down:

double down = Math.Floor(avg);

Round up:

double up = Math.Ceiling(avg);

Banker’s rounding:

Math.Round(avg, 2, MidpointRounding.ToEven);

Which Method Should You Use?

✔ Easiest

numbers.Average()

✔ Most readable

numbers.Average(x => x.Value)

✔ Best performance

Manual loop with long sum

✔ Zero-allocation

Span<T> method

✔ Best for financial accuracy

decimal + LINQ

✔ Best for big-data

Streaming / online average

✔ Best for multi-core

PLINQ .AsParallel().Average()