仅用LINQ对包含数值属性的对象集合求和

本文关键字:对象 集合 求和 属性 LINQ 包含数 仅用 | 更新日期: 2023-09-27 17:49:42

我有一个这样的对象模型:

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

现在我想在Order类上引入一个只读属性TotalQuantity,它应该总结所有OrderDetails的数量。

我想知道是否有比这更好的"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;
        }
    }
}

这不是一个好的解决方案,因为它通过OrderDetails迭代两次。并且不支持这样的操作(即使在Quantity类中提供了+操作符):

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

在LINQ中是否有更好的方法来构建总数?

(只是为了理论上的兴趣,一个简单的foreach循环当然也可以很好地完成它的工作。)

感谢您的反馈!

仅用LINQ对包含数值属性的对象集合求和

尝试:

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

如果你不希望每次添加都有新的Quantity对象的开销(RE注释),你可以使用这样的东西:

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

不如第一个好,比普通的foreach循环更尴尬(更慢?)

您可以在MSDN上找到更多关于Aggregate()方法的信息。