linq 分组上的克隆对象 - 复制构造函数替代

发布于 2024-09-14 07:57:13 字数 949 浏览 6 评论 0原文

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

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 个属性的对象。

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

深度克隆对象

in linq group query但是没有成功。

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

谢谢

I have collection of custom objects(assets) which I want to group with LINQ.
Custom object has standard properties like id, name and cost property.
When grouping I want to calculate cost for each group, so I'm using little trick like this:

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

Ok, everything is fine here. But...in order to initialize order properties as well, I'm using copy contructor and cost calculations together...

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()
                 }

So now, I get collection of grouped assets by id, with all properties copied from a first asset in a group with calculated grouped cost. But...in order to do that I need to write for every object that using this kind of grouping, a copy constructor with 'all properties initialization' which in my case is overhead because there are objects with 20+ properties.

I've tried to use clone trick from a link:

Deep cloning objects

in linq group query but with no success.

My question: is there a better/more elegant way to accomplish this?

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

宁愿没拥抱 2024-09-21 07:57:13

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

编辑以包括注释中描述的辅助方法:

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()
             })

If you don't need deep copy them you can use MemberwiseClone method. The implementation (comes from Object class) & gives you a shallow copy. So line new Asset(ga.FirstOrDefault())
will become ((Asset)(ga.FirstOrDefault().MemberwiseClone())).
However, being shallow copy, [First Asset].SomeObject would point to [Grouped Asset].SomeObject and changes from one would reflect at other.

Edited to include helper method described in comments:

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

Now, you may use the method as follows:

select Utility.CloneAndUpdate(ga.FirstOrDefault(), a =>
             {
                AssetId = ga.Key,
                Cost = ga.Select(gg=>gg.Cost).Sum()
             })
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文