LINQ对象聚合

时间:2015-08-06 14:22:59

标签: c# performance linq aggregation

我经常看到这类代码作为在c#中聚合对象可枚举的示例:

IEnumerable<MyCoolObject> myObjects = new List<MyCoolObject>()
{new MyCoolObject(){Value1=1, Value2=10}, new MyCoolObject(){Value1=2, Value2=20}};
MyCoolObject aggregatedObject = myObjects.Aggregate(new MyCoolObject(), (accumlator, next) => new MyCoolObject()
{ 
    Value1=accumlator.Value1 + next.Value1, 
    Value2=accumlator.Value2 + next.Value2
}

我对这种方法的问题是它每次迭代都会创建一个新的MyCoolObject,这似乎是一个巨大的浪费。

另一个常见的例子是:

MyCoolObject aggregatedObject = new MyCoolObject()
{
    Value1=myObjects.Sum(x=>x.Value1),
    Value2=myObjects.Sum(x=>x.Value2)
}

这一次迭代我的收藏两次,如果有更多的字段聚集在我的对象上,也可能是一个很大的浪费。

我想的是,我能做到这一点:

MyCoolObject aggregatedObject = myObjects.Aggregate(new MyCoolObject(), (accumlator, next) =>
{ 
    accumlator.Value1 += next.Value1;
    accumlator.Value2 += next.Value2;
    return accumlator;
};

这个创建一个累加器对象,对其起作用,并在完成后返回它。对我而言,这看起来与手动foreach循环性能相当。 我很惊讶,我经常看不到这个解决方案。这个解决方案有什么问题可以解释吗?

1 个答案:

答案 0 :(得分:2)

常见的用法是修改累加器然后返回它,而不是创建新对象。在这种情况下,我希望看到以下代码:

var aggregatedObject = myObjects.Aggregate(new MyCoolObject(),
    (accumulator, next) => {
       accumulator.Value1 +=next.Value1;
       accumulator.Value2 +=next.Value2;
       return accumulator;
    });

仅当修改累加器具有副作用时,才从累积函数返回新对象。一个好的累加器对象虽然会产生副作用。在这种情况下,最好使用不同的对象类型作为累加器。

相关问题