9

我有一个代表业务数据的对象。

基本上,它是一个汇总一些总数的对象:

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

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

谢谢

4

4 回答 4

6

您可以编写自己的扩展方法来包装调用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);
于 2013-07-18T08:09:03.683 回答
5

编写自己的扩展方法:

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();
于 2013-07-18T08:03:55.160 回答
0

为了使用,Sum您应该提供Func<MyClass, ###>委托,在哪里是,,,,,###或它们的可为空的对应物。所以你无法以你想要的方式使用。intlongfloatdoubledecimalMyClass

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

于 2013-07-18T08:12:17.917 回答
0

可能有点晚了……

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

List<MyClass> myClasses;
...

MyClass myClassSum = myClasses.Aggregate(func: (result, item) => result + item);
于 2021-08-13T12:07:28.560 回答