I've an object that represent a business data.
Basically, it's an object agregating some totals:
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've an IEnumerable<MyClass> myClasses
, Is there somethings I can implement in MyClass to make this:?
myClasses.Sum(d=>d);
Because for me, the way an object is additioned must be the knowledge of the object and not the caller(if one day I've one data more, I don't want to look in my whole code to see where it is used).
Thank you
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;
}
Usage:
var sum = myClasses.Sum();
You can write your own extension method that wraps a 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 would be called by:
MyClass sum = myClasses.Sum();
Or even go one step further, generalize, and include a 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 would be called as you suggest:
MyClass sum = myClasses.Sum(d => d);
As well as from complex types containing a 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);
In order to use Sum
you should provide Func<MyClass, ###>
delegate, where ###
is int
, long
, float
, double
, decimal
or their nullable counterparts.
So you are not able to use MyClass
in the way you want.
All overloads of Sum
method returns primitive types that I mentioned above. That's why it doesn't make sense to sum custom object while returning type is not a number but custom object too.