LINQ 对象聚合
LINQ object 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;
};
这个创建了一个累加器对象,对其进行处理,并在完成后 returns 它。对我来说,这看起来与手动 foreach 循环的性能相当。
我很惊讶,我不经常看到这个解决方案。这个解决方案有什么问题可以解释吗?
通常的用法是修改累加器然后 return 它,而不是创建一个新对象。在这种情况下,我希望看到以下代码:
var aggregatedObject = myObjects.Aggregate(new MyCoolObject(),
(accumulator, next) => {
accumulator.Value1 +=next.Value1;
accumulator.Value2 +=next.Value2;
return accumulator;
});
只有当修改累加器有副作用时,从累加函数返回一个新对象才有意义。一个好的累加器对象应该 不会 产生副作用。在这种情况下,最好使用不同的对象类型作为累加器。
我经常看到这样一段代码作为在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;
};
这个创建了一个累加器对象,对其进行处理,并在完成后 returns 它。对我来说,这看起来与手动 foreach 循环的性能相当。 我很惊讶,我不经常看到这个解决方案。这个解决方案有什么问题可以解释吗?
通常的用法是修改累加器然后 return 它,而不是创建一个新对象。在这种情况下,我希望看到以下代码:
var aggregatedObject = myObjects.Aggregate(new MyCoolObject(),
(accumulator, next) => {
accumulator.Value1 +=next.Value1;
accumulator.Value2 +=next.Value2;
return accumulator;
});
只有当修改累加器有副作用时,从累加函数返回一个新对象才有意义。一个好的累加器对象应该 不会 产生副作用。在这种情况下,最好使用不同的对象类型作为累加器。