17

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 ...

Vishal
  • 12,133
  • 17
  • 82
  • 128

6 Answers6

23
int s = listofshorts.Sum(d => d);
Giuseppe Accaputo
  • 2,642
  • 17
  • 23
  • This is good. An explicit cast *is not absolutely necessary*, but you would need to provide this simple lambda. (The `Sum` method for `IEnumerable` is missing the parameter-less overload.) – Anthony Pegram Aug 03 '10 at 15:13
  • @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 ;) – Giuseppe Accaputo Aug 03 '10 at 15:28
  • 2
    Who needs VS open? Use [Linqpad](http://www.linqpad.net/) for quick validation that code works. – Kilanash Aug 27 '10 at 20:51
7

You can provide the lambda for the method:

List<short> listofshorts= new List<short>(); 
int s = listofshorts.Sum(a => (int)a);
cjk
  • 45,739
  • 9
  • 81
  • 112
4
// 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:

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Mark Brackett
  • 84,552
  • 17
  • 108
  • 152
  • I am frankly surprised there is not a `short` version of Sum. Talk about a dropped ball. Edit: oh yeah, +1. :) – Randolpho Aug 03 '10 at 15:14
  • 4
    -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 Aug 03 '10 at 15:15
  • oh well. It was good in theory! +1 to Jon for actually testing it *in practice*, prompting me to do the same. – Anthony Pegram Aug 03 '10 at 15:21
  • 1
    Good catch - I didn't realize they had changed the behavior...I hate breaking changes. ;) – Mark Brackett Aug 03 '10 at 16:52
2

You could do

int s = listofshorts.Aggregate((i1,i2) => i1+i2); 
Jens
  • 25,229
  • 9
  • 75
  • 117
  • 2
    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 Aug 03 '10 at 15:30
1

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
  • 15,701
  • 14
  • 61
  • 104
0

I would probably chose the .ForEach() extension, you don't need any casting here

short sum = 0;
myListOfShort.ForEach(val => sum += val)
JackNova
  • 3,911
  • 5
  • 31
  • 49