2013-07-18 31 views
6

我有一個代表業務數據的對象。Linq SUM對象?

基本上,它是一個對象agregating有些合計:

public class MyClass{ 
    public double MyDataOne {get;set;} 
    public double MyDataTwo {get;set;} 
    public double MyDataThree {get;set;} 

    public static MyClass operator +(MyClass data1, MyClass data2){ 
     return new MyClass{MyDataOne = data1.MyDataOne + data2.MyDataOne, MyDataTwo=data1.MyDataTwo+data2.MyDataTwo, MyDataThree=data1.MyDataThree+data2.MyDataThree }; 
    } 
} 

現在,如果我有一個IEnumerable<MyClass> myClasses,是有些事我可以在MyClass的實現,使這個:?

myClasses.Sum(d=>d); 

因爲對我來說,一個對象additioned的方式必須是對象的知識,而不是調用者(如果有一天,我的一個數據比較多,我不希望在我的整個代碼看看看看它在哪裏使用)。

謝謝

+0

http://stackoverflow.com/a/13661394/1714342它解釋了一些東西 – wudzik

回答

4

寫自己的擴展方法:

public static MyClass Sum(this IEnumerable<MyClass> source) 
{ 
    var result = new MyClass(); // all data will be zeros 

    foreach(var item in source) 
     result = result + item; 

    return result; 
} 

用法:

var sum = myClasses.Sum(); 
+1

如果你還可以通過引入一些叫做'可設置'的接口使它更通用化,併爲所有'IEnumerable 其中T:可設置':) – wudzik

+1

@wudzik'YAGNI' :)他只有一個這種行爲的業務類 –

+0

@wudzik謝謝。我只是補充說我創建了一個接口,以確保我總結的類實現了在參數中帶有IEnumerable列表的'Sum'方法。像這樣我不創造許多中間元素 – J4N

5

您可以編寫一個封裝了調用自己的擴展方法來IEnumerable<T>.Aggregate這反過來又要求你超載operator +

public static MyClass Sum(this IEnumerable<MyClass> collection) 
{ 
    return collection.Aggregate((a, b) => a + b); 
} 

這將通過被稱爲:

MyClass sum = myClasses.Sum(); 

甚至走一步,歸納,幷包括一個選擇:

public static MyClass Sum<T>(this IEnumerable<T> collection, 
    Func<T, MyClass> selector) 
{ 
    return collection.Aggregate(new MyClass() /*start with an empty MyClass*/, 
     (a, b) => a + selector(b)); 
} 

正如你提到的這被稱爲:

MyClass sum = myClasses.Sum(d => d); 

以及包含的複雜類型例如:

class Foo 
{ 
    public MyClass Bar {get; set;} 
    public int Baz {get; set;} 
} 

var FooList = new List<Foo>(); 

MyClass sumOfFooListsBars = FooList.Sum(f => f.Bar); 
0

爲了使用Sum你應該提供Func<MyClass, ###>代表,其中###intlongfloatdoubledecimal或他們可爲空的同行。 所以你不能按照你想要的方式使用MyClass

Sum方法的所有重載都會返回上面提到的基本類型。這就是爲什麼總結自定義對象沒有意義,而返回類型不是數字而是自定義對象。