Sum a collection of objects which contain numeric properties only with LINQ
I have an object model like this:
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 + q开发者_JAVA百科uantity2.Volume
};
}
}
public class OrderDetail
{
public Quantity Quantity { get; set; }
}
public class Order
{
public IEnumerable<OrderDetail> OrderDetails { get; set; }
}
Now I want to introduce a readonly property TotalQuantity
on the Order
class which should sum up the quantities of all OrderDetails.
I am wondering if there is better "LINQ way" than this:
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;
}
}
}
It's not a nice solution as it iterates twice through the OrderDetails. And something like this is not supported (even though a + operator is provided in the Quantity class):
Quantity totalQuantity = OrderDetails.Sum(o => o.Quantity); // doesn't compile
Is there a better way to build the total sum in LINQ?
(Just for theoretical interest, a simple foreach loop would also do its job well of course.)
Thanks for feedback!
Try:
OrderDetails.Select(o => o.Quantity).Aggregate((x, y) => x + y)
If you'd prefer not to have the overhead of the new Quantity object for each addition (RE comment), you could use something like:
new Quantity {
Weight = OrderDetails.Select(o => o.Quantity.Weight).Sum(),
Volume = OrderDetails.Select(o => o.Quantity.Volume).Sum()
};
Not as nice as the first one, and slightly more awkward (and slower?) than just the plain foreach
loop.
You can find more about the Aggregate()
method on MSDN.
精彩评论