web-dev-qa-db-ja.com

C#でオブジェクトのコピーを作成する方法

クラスがあるとしましょう:

class obj
{
  int a;
  int b;
}

そして、私はこのコードを持っています:

obj myobj = new obj(){ a=1, b=2}
obj myobj2 = myobj;

これで、上記のコードは最初のobjへの参照を作成します。私が欲しいのはmyobj2myobjのコピーを指し、変更はオリジナルには反映されません。私はSOを検索しましたが、これまでの解決策は複雑に思えます。これを行う簡単な方法はありますか。私は.net 4.5を使用しています

35
Win Coder

オブジェクトのプロパティは値型であり、次のような状況でシャローコピーを使用できます。

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] _、OnSerializingOnSerialized。すべての場合で、StreamingContextは引数としてメソッド(およびISerializableインターフェイスの場合は特別なコンストラクター)に渡されます。 ContextStateCloneに設定すると、シリアル化の目的についてそのメソッドにヒントを与えるだけです

追加情報:(この記事は [〜#〜] msdn [〜#〜] からも読むことができます)

浅いコピーは新しいオブジェクトを作成し、現在のオブジェクトの非静的フィールドを新しいオブジェクトにコピーしています。フィールドが値型の場合、フィールドのビットごとのコピーが実行されます。参照タイプの場合、参照はコピーされますが、参照されるオブジェクトはコピーされません。したがって、元のオブジェクトとそのクローンは同じオブジェクトを参照します。

Deep copyは新しいオブジェクトを作成し、現在のオブジェクトの非静的フィールドを新しいオブジェクトにコピーしています。フィールドが値型の場合、フィールドのビットごとのコピーが実行されます。フィールドが参照タイプの場合、参照オブジェクトの新しいコピーが実行されます。

83
Farhad Jabiyev

MemberwiseClone を使用できます

obj myobj2 = (obj)myobj.MemberwiseClone();

コピーは浅いコピーです。つまり、クローンの参照プロパティは元のオブジェクトと同じ値を指しますが、objのプロパティは値型であるため、問題になることはありません。

ソースコードを所有している場合は、 ICloneable を実装することもできます

4
vc 74