3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援→開発戻り浦島太郎状態の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。

(.Net)インスタンスをコピーしたい

今回はあるインスタンスをコピーしたいという時に使える方法です。(もちろん参照のコピーではなく、あるインスタンスをメモリ空間ごとガバッとコピーすることです。)

1つにはあるインスタンスをループでまわして、フィールドをコピーすると方法がありますが、あまり現実的ではないでしょう。(なぜならフィールド数が多いとそれだけコードが増えるし、Publicなフィールドしかコピーできないからです)

ひとつが、System.Object.MemberwiseClone メソッドを使用する方法があるようです。

MemberwiseCloneメソッドはコピーしたいクラスに、System.ICloneable インターフェイスを実装しないと使えないようです。

(MemberwiseCloneメソッドはプロテクト メソッドなので、これを公開するためにSystem.ICloneable インターフェイスを実装するみたいです)

注意点は

    1.MemberwiseCloneメソッド、実装しないといけないICloneable.Clone メソッドの戻り値はObject型になるので明示的にキャストしないといけないこと。

    2.これはシャローコピー(簡易コピー)と呼ばれるものらしくて、インスタンス内の値型のフィールドはコピーするが、参照型のフィールドは参照(Cでポインタ)しかコピーしないこと。(ということはコピー元のAという参照型フィールドとコピーされたAという参照型フィールドは同じということですな)

じゃあ、参照型フィールドでも参照先のインスタンスをコピーしたい場合は?という疑問がわいてきますが、その方法もあるようです。

この方法をディープコピー(詳細コピー)というらしいです。

で、どんなふうにするのかとうのをじゃんぬさんの記事のコード見ると、コピー対象となるクラス内で、簡易コピーしてから、参照フィールドをColone(Implements System.ICloneableの実装)するという感じでした。

なるほど。でも結局は参照フィールド数しないとコピーしなおさないといけないのか。。

ほかにもっと手間かからない方法ないかなと探していると、こういう記事を見つけました。

(vb.netこちら)

オブジェクトをシリアライズし、それを別オブジェクトにデシリアライズするという方法みたいです。

条件としてはオブジェクトがシリアライズ化できること。(これが結構めんどかった。。特に外部DLLのインスタンスを持ってるときとか。)

読みやすいコードも載っています。

が、まだ自分が勉強不足なためシリアライズがなんなのかは詳しく分かっていません。

Javaでも使われてるようですが、わからないとはJavaをやってたのに恥ずかしい。

ま、概略はインスタンス化してるデータを外部でも使えるようにバイナリ化したりだとか、ネットワークに流すだとかすることみたいです。

いづれによせ、これでインスタンス丸ごとコピーできるので使い勝手はいいですね。