複雑なオブジェクト モデルでディープ クローンを実行する必要があります。.Net でそれを行う最善の方法は何だと思いますか?
シリアライズ/デシリアライズについては
、言うまでもなくMemberwiseClone
十分ではないと考えました。
7 に答える
オブジェクト モデルを制御する場合は、それを行うためのコードを記述できますが、多くのメンテナンスが必要です。ただし、多くの問題があります。つまり、絶対に最速のパフォーマンスが必要でない限り、シリアライゼーションが最も扱いやすい解決策であることがよくあります。
これは、問題なく機能するケースの 1 つBinaryFormatter
です。通常、私はファンではありません (バージョン管理などの問題のため) - しかし、シリアル化されたデータはすぐに使用できるため、これは問題ではありません。
少し速くしたい場合(ただし、独自のコードは必要ありません)、protobuf-net
役立つ場合がありますが、コードの変更が必要です(必要なメタデータなどを追加するため)。また、ツリーベースです (グラフベースではありません)。
他のシリアライザー ( XmlSerializer
、DataContractSerializer
) も問題ありませんが、単にクローンを作成する場合は、あまり提供されない可能性がありますBinaryFormatter
( .XmlSerializer
[Serializable]
本当に、それはあなたの正確なクラスとシナリオに依存します.
msdn マガジンからのディープ クローニングの例:
Object DeepClone(Object original)
{
// Construct a temporary memory stream
MemoryStream stream = new MemoryStream();
// Construct a serialization formatter that does all the hard work
BinaryFormatter formatter = new BinaryFormatter();
// This line is explained in the "Streaming Contexts" section
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
// Serialize the object graph into the memory stream
formatter.Serialize(stream, original);
// Seek back to the start of the memory stream before deserializing
stream.Position = 0;
// Deserialize the graph into a new set of objects
// and return the root of the graph (deep copy) to the caller
return (formatter.Deserialize(stream));
}
非常に優れた記事C# Object Clone Warsをご覧ください。私はそこに非常に興味深い解決策を見つけました:コピー可能: .NET オブジェクトをコピーまたは複製するためのフレームワーク
多くの場合、.Netシリアライザーよりも高速なAltSerializeを試すことができます。また、シリアル化を高速化するためのキャッシュとカスタム属性も提供します。
これを手動で実装する最良の方法。他の一般的な方法よりも本当に高速です。また、この操作には多くのライブラリがあります (パフォーマンス ベンチマークのリストはこちらで確認できます)。
ところで、BinaryFormatter はこのタスクでは非常に遅く、テストにのみ適しています。
おそらく最善の方法は、オブジェクトとそのすべてのフィールドに System.IClonable インターフェイスを実装することです。これにはカスタムのディープ クローニング機能も必要です。次に、 Cloneメソッドを実装して、オブジェクトとそのメンバーのディープ コピーを返します。