Linq sum at the facilities?

I have an object representing business data.

In principle, this is an object that aggregates some results:

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

Now, if I have an IEnumerable<MyClass> myClasses , is there something I can implement in MyClass to do this :?

 myClasses.Sum(d=>d); 

Because for me, the way to add an object should be to know the object, not the caller (if one day I have one more information, I don’t want to look at all my code to see where it is used).

thanks

+6
source share
3 answers

Write your own extension method:

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

Using:

 var sum = myClasses.Sum(); 
+4
source

You can write your own extension method that ends the call to IEnumerable<T>.Aggregate , which in turn calls your overloaded operator + :

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

This will be called:

 MyClass sum = myClasses.Sum(); 

Or even take another step, summarize and enable the 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)); } 

This will be triggered as you suggest:

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

Like complex types containing MyClass , for example:

 class Foo { public MyClass Bar {get; set;} public int Baz {get; set;} } var FooList = new List<Foo>(); MyClass sumOfFooListsBars = FooList.Sum(f => f.Bar); 
+5
source

To use Sum , you must provide a delegate Func<MyClass, ###> , where ### is int , long , float , double , decimal or their nullable copies. Thus, you cannot use MyClass way you want.

All overloads of the Sum method return the primitive types that I mentioned above. Therefore, it makes no sense to summarize the user object, while the return type is not a number, nor is it a custom object.

0
source

Source: https://habr.com/ru/post/949718/


All Articles