2015-08-06 2 views
1

Я часто вижу такой кусок кода в качестве примера агрегирования перечислимого объекта в C#:LINQ агрегация объекта

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

Это одна итерация мою коллекцию дважды, также большие отходы, espetially, если есть несколько полей для агрегирования моих объектов.

То, что я понял, есть, я мог бы сделать это:

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

Это один создает один объект accumlator, работает на него, и возвращает ее, когда закончите. Для меня это выглядит наравне с ручным циклом foreach. Я удивлен, что часто не вижу этого решения. Есть ли какие-либо проблемы, которые может возникнуть в этом решении, что могло бы объяснить это?

+2

1) Приведенные вами примеры являются * не * распространенными. 2) Ваш код * также создает * один временный объект для каждой строки ввода. Это опечатка? 3) Обычное использование заключается в том, чтобы добавить текущее значение к аккумулятору и вернуть аккумулятор –

+1

@PanagiotisKanavos. Я подозреваю, что создание объекта в его предлагаемом коде является только опечаткой. Кроме этого, я согласен с вами. :) – Venemo

+1

Действительно, создание нового объекта было опечаткой. Никогда не копируйте ваш плохой пример. – Robert

ответ

2

Общее использование заключается в изменении аккумулятора, а затем его возврате, а не на создание нового объекта. В этом случае, я бы ожидать, чтобы увидеть следующий код:

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

Возвращения нового объекта из функции аккумулирования имеет смысл только тогда, когда изменение аккумулятора имеет побочные эффекты. Хороший аккумуляторный объект, хотя должен не производить побочные эффекты. В таком случае было бы лучше использовать другой тип объекта в качестве аккумулятора.