【问题标题】:Sum a collection of objects which contain numeric properties only with LINQ将仅包含数字属性的对象集合与 LINQ 相加
【发布时间】:2011-04-10 15:57:30
【问题描述】:

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

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 循环当然也可以很好地完成它的工作。)

感谢您的反馈!

【问题讨论】:

    标签: c# .net linq


    【解决方案1】:

    试试:

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

    如果您不想为每次添加(RE 注释)增加新的 Quantity 对象的开销,您可以使用类似:

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

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

    您可以找到有关Aggregate() 方法on MSDN 的更多信息。

    【讨论】:

    • 在这种情况下你不需要WhateverProperty,因为TotalQuantity返回一个Quantity
    • @Thomas:谢谢。在我不断重新解释问题时进行了一系列编辑;定了这个,没想到把它拿出来。 :)
    • 太好了,它有效!谢谢!我只是再次考虑我的评论,即我在问题中的解决方案不是一个“好的解决方案”。它只创建一个 Quantity 对象,然后将小数加起来两次以构建总和,同时使用 + 重载为每个二进制加法创建一个新的 Quantity 对象。我不确定什么是更好的性能,尽管使用 + 运算符使代码看起来更友好。但这是另一个问题。
    • @Slauma:谢谢。有关两者之间的折衷,请参阅新的编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 2014-06-27
    • 2015-06-07
    • 2019-10-01
    • 2021-12-29
    相关资源
    最近更新 更多