クラスがあるとしましょう:
class obj
{
int a;
int b;
}
そして、私はこのコードを持っています:
obj myobj = new obj(){ a=1, b=2}
obj myobj2 = myobj;
これで、上記のコードは最初のobjへの参照を作成します。私が欲しいのはmyobj2
はmyobj
のコピーを指し、変更はオリジナルには反映されません。私はSOを検索しましたが、これまでの解決策は複雑に思えます。これを行う簡単な方法はありますか。私は.net 4.5を使用しています
オブジェクトのプロパティは値型であり、次のような状況でシャローコピーを使用できます。
obj myobj2 = (obj)myobj.MemberwiseClone();
しかし、他の状況(メンバーが参照型である場合など)では、Deep Copyが必要です。 Serialization
クラスとDeserialization
クラスを使用して、BinaryFormatter
およびStreamingContext
の手法を使用して、オブジェクトのディープコピーを取得できます。
public static T DeepCopy<T>(T other)
{
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
formatter.Serialize(ms, other);
ms.Position = 0;
return (T)formatter.Deserialize(ms);
}
}
ISerializable
を設定する目的:OnDeserialized
インターフェイスを実装するか、OnDeserializing
、_などの組み込み属性を使用して、コードに特別なシリアル化および逆シリアル化ロジックを導入できます。 [$ var] _、OnSerializing
、OnSerialized
。すべての場合で、StreamingContext
は引数としてメソッド(およびISerializable
インターフェイスの場合は特別なコンストラクター)に渡されます。 ContextState
をClone
に設定すると、シリアル化の目的についてそのメソッドにヒントを与えるだけです。
追加情報:(この記事は [〜#〜] msdn [〜#〜] からも読むことができます)
浅いコピーは新しいオブジェクトを作成し、現在のオブジェクトの非静的フィールドを新しいオブジェクトにコピーしています。フィールドが値型の場合、フィールドのビットごとのコピーが実行されます。参照タイプの場合、参照はコピーされますが、参照されるオブジェクトはコピーされません。したがって、元のオブジェクトとそのクローンは同じオブジェクトを参照します。
Deep copyは新しいオブジェクトを作成し、現在のオブジェクトの非静的フィールドを新しいオブジェクトにコピーしています。フィールドが値型の場合、フィールドのビットごとのコピーが実行されます。フィールドが参照タイプの場合、参照オブジェクトの新しいコピーが実行されます。
MemberwiseClone を使用できます
obj myobj2 = (obj)myobj.MemberwiseClone();
コピーは浅いコピーです。つまり、クローンの参照プロパティは元のオブジェクトと同じ値を指しますが、obj
のプロパティは値型であるため、問題になることはありません。
ソースコードを所有している場合は、 ICloneable を実装することもできます