オブジェクトのコピー。ICloneableインタフェース、MemberWiseClone、シリアライズを利用したインスタンスのコピー。

オブジェクトをコピーするためにはMemberwiseCloneメソッドを使用します。MemberwiseCloneメソッドは、シャローコピー(浅いコピー)と呼ばれるコピーで値型のメンバーをコピーして新しいインスタンスを作成する方法です。参照型のメンバーに関しては、参照ポインタをコピーするので実際はコピーしても同じオブジェクトを指したままとなります。これは大事な注意点でオブジェクトをコピーしたつもりが実はコピーできていないという誤解が良くあります。

MemberWiseCloneメソッドを利用するには、ICloneableインタフェースを継承します。


Public Class Form1

Public Class Item
Implements ICloneable

Public Name As String
Public Job As String
Public Child As Item

Public Function Clone() As Object Implements System.ICloneable.Clone
Return Me.MemberwiseClone()
End Function

End Class

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim parent As New Item
Dim child As New Item

parent.Name = "taro"
parent.Job = "system engineer"
parent.Child = child

child.Name = "taro.jr"
child.Job = "programmer"

Dim parent2 As Item = parent.Clone
Dim child2 As Item = child.Clone

parent2.Name += "2"
child2.Name += "2"

Debug.Print(parent2.Child.Name)

End Sub
End Class

この時、上記の処理の結果はtaro.jr2となりません。参照型はポインタをコピーしているだけだからです。


Debug.Print(parent2.Child.Name)

参照型のメンバーが指しているオブジェクトも含めてコピーをする場合。これをディープコピー(深いコピー)といいます。はコピー処理を独自に実装する必要がでてきます。実装方法で一番簡単なのはシリアライズを利用する方法です。参照型が指すオブジェクトも含めてインスタンスのコピーを作成することができます。シリアライズしたいオブジェクト、そのオブジェクトが参照しているオブジェクトと関連するオブジェクトのすべてにSystem.Serializable属性を付けておけば、シリアライズによるコピーが可能になります。

シリアライズの方法は以下を参照してください。

BinaryFormatterを使用してインスタンスをバイナリでシリアライズする。
http://d.hatena.ne.jp/tekk/20091012/1255357237