2013-07-18 6 views
6

비즈니스 데이터를 나타내는 개체가 있습니다.개체에 Linq SUM?

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의에서 구현할 수있다 일도인가, 이제 :? :

기본적으로, 약간의 합계를 agregating 객체입니다

myClasses.Sum(d=>d); 

나를 위해, 객체가 additioned되는 방법은 개체의 지식이 아닌 호출해야하기 때문에 (언젠가는 하나 개의 데이터보다, 내 전체 코드에서보고 싶지 않은 한 경우 어디에서 사용되는지 확인하십시오).

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

사용법 :

+0

http://stackoverflow.com/a/13661394/1714342 뭔가 설명합니다. – wudzik

답변

4

자신의 확장 방법을 쓰기 감사

var sum = myClasses.Sum(); 
+1

또한 'ISumable'이라는 인터페이스를 도입하여 좀 더 포괄적으로 만들 수 있고 모든 IEnumerable 에 대한 일반 확장을 만들 수있는 경우 T : ISumable ':) – 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(); 

또는과 선택을 포함한다 : 6,

이가 호출 될

당신이 제안으로 불려 될
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

당신이 ###int, long, float, double, decimal 또는 널 (NULL) 대응입니다 Func<MyClass, ###> 대리자를 제공해야 Sum 사용하려면. 따라서 원하는 방식으로 MyClass을 사용할 수 없습니다.

Sum의 모든 오버로드는 위에서 언급 한 프리미티브 유형을 반환합니다. 그렇기 때문에 유형을 반환하는 것은 숫자가 아니지만 사용자 정의 객체이기도하지만 사용자 정의 객체를 합치는 것은 의미가 없습니다.