2013-07-18 61 views
6

Tôi là một đối tượng đại diện cho dữ liệu doanh nghiệp.LINQ SUM trên các đối tượng?

Về cơ bản, nó là một đối tượng agregating một số tổng số:

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

Bây giờ, nếu tôi đã một IEnumerable<MyClass> myClasses, Có somethings tôi có thể thực hiện trong MyClass để làm điều này :?

myClasses.Sum(d=>d); 

Vì đối với tôi, cách đối tượng được thêm vào phải là kiến ​​thức về đối tượng chứ không phải người gọi (nếu một ngày tôi có thêm dữ liệu, tôi không muốn xem toàn bộ mã của mình để xem nơi nó được sử dụng).

Cảm ơn bạn

+0

http://stackoverflow.com/a/13661394/1714342 nó giải thích điều gì đó – wudzik

Trả lời

4

Viết phương pháp khuyến nông của riêng bạn:

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

Cách sử dụng:

var sum = myClasses.Sum(); 
+1

Và nếu bạn cũng có thể làm cho nó trở nên chung chung hơn bằng cách giới thiệu một số giao diện gọi là 'ISumable' và tạo phần mở rộng chung cho tất cả' IEnumerable trong đó T: ISumable ':) – wudzik

+1

@wudzik' YAGNI' :) Anh ấy chỉ có một lớp học kinh doanh với hành vi này –

+0

@wudzik Cảm ơn bạn. Tôi sẽ chỉ thêm rằng tôi tạo ra một giao diện, để đảm bảo rằng lớp mà trên đó tôi tổng hợp thực hiện một phương thức 'Sum' mà có một danh sách IEnumerable trong tham số. Như thế này tôi không tạo ra nhiều yếu tố trung gian – J4N

5

Bạn có thể viết phương pháp khuyến nông của riêng bạn mà kết thúc tốt đẹp một cuộc gọi đến IEnumerable<T>.Aggregate nó sẽ gọi bạn quá tải operator +:

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

này sẽ được gọi bởi:

MyClass sum = myClasses.Sum(); 

Hoặc thậm chí đi một bước xa hơn, khái quát, và bao gồm một selector:

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

này sẽ được gọi là bạn đề nghị:

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

Cũng như từ các loại phức tạp có chứa MyClass ví 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

Để sử dụng Sum bạn nên cung cấp Func<MyClass, ###> đại biểu, nơi ###int, long, float, double, decimal hoặc đối tác nullable của họ. Vì vậy, bạn không thể sử dụng MyClass theo cách bạn muốn.

Tất cả các quá tải của phương pháp Sum trả về các kiểu nguyên thủy mà tôi đã đề cập ở trên. Đó là lý do tại sao nó không có ý nghĩa để tổng hợp đối tượng tùy chỉnh trong khi trở về loại không phải là một số nhưng đối tượng tùy chỉnh quá.

Các vấn đề liên quan