1

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以上のプロパティを持つオブジェクトがあるためオーバーヘッドです。

リンクからクローントリックを使用しようとしました:

オブジェクトのディープ クローニング

linq グループクエリでは成功しませんでした。

私の質問:これを達成するためのより良い/よりエレガントな方法はありますか?

ありがとうございました

4

1 に答える 1

2

それらをディープ コピーする必要がない場合は、MemberwiseClone メソッドを使用できます。実装(オブジェクトクラスからのもの)&は、浅いコピーを提供します。したがって、行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()
             })
于 2010-08-11T10:07:24.210 に答える