Summarize a set of objects that contain numeric properties only with LINQ

I have an object model:

public class Quantity { public decimal Weight { get; set; } public decimal Volume { get; set; } // perhaps more decimals... public static Quantity operator +(Quantity quantity1, Quantity quantity2) { return new Quantity() { Weight = quantity1.Weight + quantity2.Weight, Volume = quantity1.Volume + quantity2.Volume }; } } public class OrderDetail { public Quantity Quantity { get; set; } } public class Order { public IEnumerable<OrderDetail> OrderDetails { get; set; } } 

Now I want to introduce the readonly TotalQuantity property in the Order class, which should sum the amounts of all OrderDetails.

I am wondering if there is a better way to "LINQ":

 public class Order { // ... public Quantity TotalQuantity { get { Quantity totalQuantity = new Quantity(); if (OrderDetails != null) { totalQuantity.Weight = OrderDetails.Sum(o => o.Quantity.Weight); totalQuantity.Volume = OrderDetails.Sum(o => o.Quantity.Volume); } return totalQuantity; } } } 

This is not a good solution, as it is repeated twice through OrderDetails. And something like this is not supported (even if the + operator is present in the Quantity class):

 Quantity totalQuantity = OrderDetails.Sum(o => o.Quantity); // doesn't compile 

Is there a better way to build the total amount in LINQ?

(For theoretical interest only, a simple foreach loop would also do its job well).

Thanks for the feedback!

+7
source share
1 answer

Try:

 OrderDetails.Select(o => o.Quantity).Aggregate((x, y) => x + y) 

If you prefer not to have the overhead of a new Quantity object for each addition (RE comment), you can use something like:

 new Quantity { Weight = OrderDetails.Select(o => o.Quantity.Weight).Sum(), Volume = OrderDetails.Select(o => o.Quantity.Volume).Sum() }; 

Not as good as the first one, and a bit more awkward (and slower?) Than a simple foreach .

You can find more about the Aggregate() method on MSDN .

+17
source

All Articles