具有运算符 + 的对象上的 Linq SUM
本文关键字:Linq SUM 对象 运算符 | 更新日期: 2023-09-27 18:23:47
我有一个表示业务数据的对象。
基本上,它是一个聚合一些总数的对象:
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);
因为对我来说,添加对象的方式必须是对象的知识,而不是调用者的知识(如果有一天我多了一个数据,我不想查看我的整个代码以查看它在哪里使用(。
谢谢
您可以编写自己的扩展方法来包装对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);
以及包含MyClass
的复杂类型,例如:
class Foo
{
public MyClass Bar {get; set;}
public int Baz {get; set;}
}
var FooList = new List<Foo>();
MyClass sumOfFooListsBars = FooList.Sum(f => f.Bar);
编写自己的扩展方法:
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();
为了使用Sum
,你应该提供Func<MyClass, ###>
委托,其中###
是int
、long
、float
、double
、decimal
或其可为空的对应项。因此,您无法以所需的方式使用MyClass
。
Sum
方法的所有重载都返回我上面提到的基元类型。这就是为什么对自定义对象求和没有意义,而返回类型不是数字而是自定义对象。
也许有点晚了...
但是,如果目标是使用实现的 +
-函数对类求和(并且不一定使用 Sum()
-函数(,则可以使用 Aggregate()
-函数
List<MyClass> myClasses;
...
MyClass myClassSum = myClasses.Aggregate(func: (result, item) => result + item);