具有运算符 + 的对象上的 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);

因为对我来说,添加对象的方式必须是对象的知识,而不是调用者的知识(如果有一天我多了一个数据,我不想查看我的整个代码以查看它在哪里使用(。

谢谢

具有运算符 + 的对象上的 Linq SUM

您可以编写自己的扩展方法来包装对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, ###>委托,其中###intlongfloatdoubledecimal或其可为空的对应项。因此,您无法以所需的方式使用MyClass

Sum方法的所有重载都返回我上面提到的基元类型。这就是为什么对自定义对象求和没有意义,而返回类型不是数字而是自定义对象。

也许有点晚了...

但是,如果目标是使用实现的 + -函数对类求和(并且不一定使用 Sum() -函数(,则可以使用 Aggregate() -函数

List<MyClass> myClasses;
...
MyClass myClassSum = myClasses.Aggregate(func: (result, item) => result + item);