2012-12-01 12 views
11

Ho un tipo personalizzato (Money) che ha una conversione implicita in decimale e un operatore sovraccarico per +. Quando ho un elenco di questi tipi e chiamo il metodo linq Sum il risultato è decimale, non Money. Come posso fornire la presidenza dell'operatore + e restituire il denaro dallo Sum?Sovraccarico dell'operatore e somma Linq in C#

internal class Test 
{ 
    void Example() 
    { 
     var list = new[] { new Money(10, "GBP"), new Money(20, "GBP") }; 
     //this line fails to compile as there is not implicit 
     //conversion from decimal to money 
     Money result = list.Sum(x => x); 
    } 
} 


public class Money 
{ 
    private Currency _currency; 
    private string _iso3LetterCode; 

    public decimal? Amount { get; set; } 
    public Currency Currency 
    { 
     get { return _currency; } 
     set 
     { 
      _iso3LetterCode = value.Iso3LetterCode; 
      _currency = value; 
     } 
    } 

    public Money(decimal? amount, string iso3LetterCurrencyCode) 
    { 
     Amount = amount; 
     Currency = Currency.FromIso3LetterCode(iso3LetterCurrencyCode); 
    } 

    public static Money operator +(Money c1, Money c2) 
    { 
     if (c1.Currency != c2.Currency) 
      throw new ArgumentException(string.Format("Cannot add mixed currencies {0} differs from {1}", 
                 c1.Currency, c2.Currency)); 
     var value = c1.Amount + c2.Amount; 
     return new Money(value, c1.Currency); 
    } 

    public static implicit operator decimal?(Money money) 
    { 
     return money.Amount; 
    } 

    public static implicit operator decimal(Money money) 
    { 
     return money.Amount ?? 0; 
    } 
} 

risposta

12

Sum conosce solo sui tipi numerici in System.

È possibile utilizzare Aggregate come questo:

Money result = list.Aggregate((x,y) => x + y); 

Perché questo sta chiamando Aggregate<Money>, userà il Money.operator+ e restituire un oggetto Money.

+3

ho finito di aggiungere i miei 'Sum' MoneyHelpers classe public static { static denaro pubblico Sum (questo IEnumerable fonte, Func selettore) {var somme = source.Select (selettore); return monies.Aggregate ((x, y) => x + y); } } – ilivewithian

+0

Ottimo suggerimento. Grazie. – Joe