views:

196

answers:

5

I was trying to do something like this -

List<short> listofshorts= new List<short>();
int s = listofshorts.Sum();
//this does not work...but same code works for a list of ints..

I got this compilation error -

'System.Collections.Generic.List' does not contain a definition for 'Sum' and the best extension method overload 'System.Linq.Queryable.Sum(System.Linq.IQueryable)' has some invalid arguments

Can anyone suggest how can I use an extension method to calculate the sum of shorts? For some reason the extension method does not support it ...

+4  A: 
// This throws an InvalidCastException in .NET 3.5 SP1+
// DO NOT USE THIS CODE
listOfShorts.Cast<int>().Sum();

In the interest of posterity, and pointing out this seemingly obvious solution doesn't work - I'm going to leave this answer with the following links about .NET 3.5 SP1+ behavior:

Mark Brackett
I am frankly surprised there is not a `short` version of Sum. Talk about a dropped ball. Edit: oh yeah, +1. :)
Randolpho
-1 because this throws an `InvalidCastException` - `Cast()` tries to unbox from a boxed `short` to `int`, which fails. I believe it would have worked in .NET 3.5 pre-SP1. (Yes, I did write a program to check :)
Jon Skeet
@Mark, oh well. It was good in theory! +1 to Jon for actually testing it *in practice*, prompting me to do the same.
Anthony Pegram
Good catch - I didn't realize they had changed the behavior...I hate breaking changes. ;)
Mark Brackett
+5  A: 

You can provide the lambda for the method:

List<short> listofshorts= new List<short>(); 
int s = listofshorts.Sum(a => (int)a);
ck
+10  A: 
int s = listofshorts.Sum(d => d);
Giu
This is good. An explicit cast *is not absolutely necessary*, but you would need to provide this simple lambda. (The `Sum` method for `IEnumerable<short>` is missing the parameter-less overload.)
Anthony Pegram
I did wonder if this would work, but didn't have VS handy to test it....
ck
@Anthony Pegram Thanks. Looks like `short` is not *in* these days ;)@ck That's the advantage of having VS always open while surfing on SO ;)
Giu
Who needs VS open? Use [Linqpad](http://www.linqpad.net/) for quick validation that code works.
Kilanash
+2  A: 

You could do

int s = listofshorts.Aggregate((i1,i2) => i1+i2); 
Jens
I think you're trying to kill the fly with a sledgehammer. Your procedure, IMHO, is a super-complicated way of solving a simple problem.
Alex Essilfie
+1  A: 

Like the others have suggested, you will need to cast the short objects to a type which is supported by the Enumerable.Sum method. Unfortunately there are no overloaded Sum method for some of the types like ulong, etc.

If you're gonna be needing it very often though, I'd recommend writing an extension method yourself, here's one I did a while back for ulong and ulong?, you can do something very similar for short or any other types you need:

    public static ulong Sum(this IEnumerable<ulong> source)
    {
        var sum = 0UL;

        foreach (var number in source)
        {
            sum += number;
        }

        return sum;
    }

    public static ulong? Sum(this IEnumerable<ulong?> source)
    {
        var sum = 0UL;

        foreach (var nullable in source)
        {
            if (nullable.HasValue)
            {
                sum += nullable.GetValueOrDefault();
            }                
        }

        return sum;
    }

P.S. my implementations are based on the Enumerable.Sum implementation after I took a peek with reflector purely out of curiosity :-P

theburningmonk