Extension methods to sum IEnumerable(ulong) and IEnumerable(ulong?)

Ever tried to use IEnumerable<T>.Sum on an array of unsigned long integers? Well, you can’t, because the Sum method has not been implemented for ulong or ulong?, so to fill in the gap here’s the extension methods you need using more or less the same code as the existing Sum methods:

[CheckParameters]
public static ulong Sum([NotNull] this IEnumerable<ulong> source)
{
    var sum = 0UL;
    foreach (var number in source)
    {
        sum += number;
    }
    return sum;
}

[CheckParameters]
public static ulong? Sum([NotNull] this IEnumerable<ulong?> source)
{
    var sum = 0UL;
    foreach (var nullable in source)
    {
        if (nullable.HasValue)
        {
            sum += nullable.GetValueOrDefault();
        }
    }
    return sum;
}

[CheckParameters]
public static ulong Sum<T>([NotNull] this IEnumerable<T> source, Func<T, ulong> selector)
{
    return source.Select(selector).Sum();
}

[CheckParameters]
public static ulong? Sum<T>([NotNull] this IEnumerable<T> source, Func<T, ulong?> selector)
{
    return source.Select(selector).Sum();
}

I used some custom PostSharp attributes here to do the parameter validation, but you can just as easily substitute them with if null then throw exception code blocks.

UPDATE 10/11/2010:

Using the dynamic type in .Net 4 you can make these extension methods even more useful by making them usable with other value types too.

Traditionally for extension methods like Sum, you’d have to provide an overload for each numeric value type (int, uint, long, etc.) because these numeric value types don’t have a common super type which defines the numeric operators +, -, /, *, etc.

Fortunately, you can now negate this compile time limitation by making it a runtime decision using the new dynamic capabilities:

public static T Sum<T>(this IEnumerable<T> source) where T : struct
{
    return source.Aggregate(default(T), (current, number) => (dynamic) current + number);
}
public static T? Sum<T>(this IEnumerable<T?> source) where T : struct
{
    return source.Where(nullable => nullable.HasValue)
                 .Aggregate(
                     default(T),
                     (current, nullable) => (dynamic) current + nullable.GetValueOrDefault());
}
public static V Sum<T, V>(this IEnumerable<T> source, Func<T, V> selector) where V : struct
{
    return source.Select(selector).Sum();
}
public static V? Sum<T, V>(this IEnumerable<T> source, Func<T, V?> selector) where V : struct
{
    return source.Select(selector).Sum();
}

The obvious fallacy with this approach is that you can now pass custom structures with no defined + operator into these extension methods and no compile errors will be thrown, but a RuntimeBinderException will be thrown by the DLR at runtime with a message like this:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Operator ‘+’ cannot be applied to operands of type ‘xxx’ and ‘xxx’

Liked this article? Support me on Patreon and get direct help from me via a private Slack channel or 1-2-1 mentoring.
Subscribe to my newsletter


Hi, I’m Yan. I’m an AWS Serverless Hero and the author of Production-Ready Serverless.

I specialise in rapidly transitioning teams to serverless and building production-ready services on AWS.

Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.

Hire me.


Check out my new course, Complete Guide to AWS Step Functions. In this course, we’ll cover everything you need to know to use AWS Step Functions service effectively. Including basic concepts, HTTP and event triggers, activities, callbacks, nested workflows, design patterns and best practices.

Get Your Copy