5


1

C#で相互接続オブジェクトをディープクローンする方法

相互接続されたオブジェクトのセットを*ディープ*クローンするための最善の方法は何ですか? 例:

class A {
    B theB; // optional
    // ...
}

class B {
    A theA; // optional
    // ...
}

class Container {
    A[] a;
    B[] b;
}

するべき明白なことは私がそれに来るように物を歩きそして深くすべてをクローン化することである。 ただし、これにより問題が発生します。「+ B 」を含む「 A 」を複製し、「 B 」も「 Container 」に含まれている場合、複製後に「 B 」が2回複製されます` Container +`。

次の論理的なステップは、 `+ Dictionary +`を作成し、クローンを作成する前にすべてのオブジェクトを検索することです。 しかしながら、これはゆっくりとした愚かな解決策かもしれないようです。

何かご意見は?

6 Answer


2


あなたが提案した辞書の解決策は私が知っている最高のものです。 さらに最適化するには、object.GetHashCode()を使用してオブジェクトのハッシュを取得し、それを辞書のキーとして使用できます。 巨大なオブジェクトツリー(数十から数十万ものオブジェクト)について話しているのでなければ、速いはずです。


2


私がC#に精通しているわけではありませんが、通常、何らかの処理のためにグラフをクロールすると、循環参照によりオブジェクトの処理を停止するためのルックアップテーブルが必要になります。 だから私はあなたがここで同じことをする必要があるだろうと思います。


2


それは確かにエレガントな解決策ではありませんが、辞書(またはハッシュマップ)を使用することは珍しくありません。 利点の1つは、ハッシュマップのルックアップ時間が一定であるため、ここでは速度があまり低下しないことです。


0


このオブジェクトが以前に複製されたことがあるかどうかを示すために、ビットフラグを作成してください。


0


もう1つ考えられる解決策は、オブジェクトをストリームに直列化してから、それらを同じストリームから新しいインスタンスに再構築することです。 これは、他のすべてがひどく複雑で面倒なように思えるとき、しばしば不思議に働きます。

マーク


0


ディープクローニングを行うための実用的な方法の1つは、ソースグラフをシリアル化してからシリアル化解除することです。 https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer(v = vs.110).aspx [+ DataContractSerializer +]のような.NETのシリアライザーもhttps://です。 msdn.microsoft.com/en-us/library/vstudio/hh241056(v = vs.100).aspx [グラフ内の処理サイクルが可能]。 http://manski.net/2014/10/net-serializers-comparison-chart/ [機能比較表]を見れば、どのシリアライザがあなたのシナリオに最適かを選択することができます。