2010-08-03 4 views
15

Stavo cercando di fare qualcosa di simile -Come ottenere la somma dell'elenco di cortometraggi utilizzando il metodo di estensione Sum()?

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

ho ottenuto questo errore di compilazione -

'System.Collections.Generic.List' non contiene una definizione per 'Sum' e la miglior metodo di estensione di sovraccarico 'System.Linq.Queryable.Sum (System.Linq.IQueryable)' ha alcuni argomenti non validi

qualcuno può suggerire come posso utilizzare un metodo di estensione per calcolare la somma di pantaloncini? Per qualche motivo il metodo di estensione non la supporta ...

risposta

21
int s = listofshorts.Sum(d => d); 
+0

Questo è buono. Un cast esplicito * non è assolutamente necessario *, ma è necessario fornire questo semplice lambda. (Il metodo 'Sum' per' IEnumerable ' manca il sovraccarico senza parametri.) –

+0

Mi chiedevo se questo avrebbe funzionato, ma non avevo VS a portata di mano per testarlo .... – cjk

+0

@Anthony Pegram Grazie. Sembra che 'short' non sia * in * in questi giorni;) @ck Questo è il vantaggio di avere VS sempre aperto durante la navigazione su SO;) –

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

Nell'interesse dei posteri, e sottolineando questa soluzione apparentemente ovvia non funziona - ho intenzione di lasciare questa risposta con i seguenti link su .NET 3.5 SP1 + comportamento:

+0

Sono francamente sorpreso che non esiste una versione "corta" di Sum. Parlare di una palla caduta. Modifica: oh sì, +1. :) – Randolpho

+4

-1 perché questo lancia un 'InvalidCastException' -' Cast() 'prova a unbox da un boxed' short' a 'int', che fallisce. Credo che avrebbe funzionato in .NET 3.5 pre-SP1. (Sì, ho scritto un programma per controllare :) –

+0

oh, va bene. Era buono in teoria! +1 a Jon per testarlo effettivamente * in pratica *, spingendomi a fare lo stesso. –

7

è possibile fornire il lambda per il metodo:

List<short> listofshorts= new List<short>(); 
int s = listofshorts.Sum(a => (int)a); 
2

si potrebbe fare

int s = listofshorts.Aggregate((i1,i2) => i1+i2); 
+2

Penso che tu stia cercando di uccidere il volo con un martello. La tua procedura, IMHO, è un modo super complicato per risolvere un semplice problema. –

1

Come gli altri hanno suggerito, è necessario lanciare gli oggetti brevi a un tipo che è supportato dal metodo Enumerable.Sum. Sfortunatamente non ci sono metodi Sum sovradimensionati per alcuni tipi come ulong, ecc.

Se ti servirà molto spesso però, ti consiglio di scrivere un metodo di estensione tu stesso, eccone uno che ho fatto un po 'indietro per ulong e ulong ?, si può fare qualcosa di molto simile per brevi o qualsiasi altro tipo di cui avete bisogno:

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; 
    } 

PS i miei implementazioni sono basate sulla realizzazione Enumerable.Sum dopo che ho preso una sbirciatina con riflettore per pura curiosità :-P

0

avrei probabilmente scelto l'estensione .ForEach(), non è necessario alcun fusione qui

short sum = 0; 
myListOfShort.ForEach(val => sum += val)