【问题标题】:cloning object on linq grouping - copy constructor substitute在 linq 分组上克隆对象 - 复制构造函数替代
【发布时间】:2011-03-28 07:08:58
【问题描述】:

我有一些我想用 LINQ 分组的自定义对象(资产)。 自定义对象具有标准属性,如 id、name 和 cost 属性。 分组时我想计算每个组的成本,所以我使用了这样的小技巧:

from a in assets
group a by a.AssetId into ga
select new Asset()
                 {
                    AssetId = ga.Key,
                    Cost = ga.Select(gg=>gg.Cost).Sum()
                 }

好的,这里一切都很好。但是...为了也初始化订单属性,我同时使用了复制构造函数和成本计算...

from a in assets
group a by a.AssetId into ga
select new Asset(ga.FirstOrDefault())
                 {
                    AssetId = ga.Key,
                    Cost = ga.Select(gg=>gg.Cost).Sum()
                 }

现在,我按 id 获取分组资产的集合,所有属性都从组中的第一个资产复制,并计算出分组成本。但是...为了做到这一点,我需要为使用这种分组的每个对象编写一个具有“所有属性初始化”的复制构造函数,在我的情况下这是开销,因为有 20 多个属性的对象。

我尝试使用链接中的克隆技巧:

Deep cloning objects

在 linq 组查询中但没有成功。

我的问题:有没有更好/更优雅的方法来实现这一点?

谢谢

【问题讨论】:

    标签: linq group-by copy-constructor


    【解决方案1】:

    如果您不需要深拷贝它们,您可以使用 MemberwiseClone 方法。实现(来自 Object 类)& 给你一个浅拷贝。所以行new Asset(ga.FirstOrDefault()) 将变为((Asset)(ga.FirstOrDefault().MemberwiseClone()))。 然而,作为浅拷贝,[First Asset].SomeObject 将指向 [Grouped Asset].SomeObject,并且从一个对象的更改将反映在另一个对象上。

    已编辑以包含 cmets 中描述的辅助方法:

    static T CloneAndUpdate<T>(T t, Action<T> updater) where T: class
    {
    T clone = null; // Use reflection/serialization to create shallow/deep clone
    updater(clone);
    return clone;
    }
    

    现在,您可以使用如下方法:

    select Utility.CloneAndUpdate(ga.FirstOrDefault(), a =>
                 {
                    AssetId = ga.Key,
                    Cost = ga.Select(gg=>gg.Cost).Sum()
                 })
    

    【讨论】:

    • 糟糕!我注意到您想使用对象初始化器 - 不确定它们是否可以在不使用构造函数的资产实例上工作。
    • 我能想到的唯一方法是添加使用 MemberwiseClone() 的复制构造函数 - 这将至少减少编写复制构造函数的时间。另一种方法是编写一个静态方法,例如 -- static T CloneAndUpdate(T t, Action updater) where T: class { T clone = ...; /* 使用反射/序列化创建克隆 */ updater(clone);返回克隆; } 然后将其用作 ---- select Utility.CloneAndUpdate(ga.FirstOrDefault(), a => { AssetId = ga.Key, Cost = ga.Select(gg=>gg.Cost).Sum() })
    • 嗯,最后的评论是一个很好的解决方案,你能把它作为答案发布吗,这样有点难以理解......谢谢:)..哦,你已经做到了......好的就是这样,非常感谢你,我喜欢你的解决方案...+1 ;) 并标记为答案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多