このヘルパー関数を呼び出すことで、任意のクラスのクローンを作成できます。
Function DeepClone(Of T)(ByRef orig As T) As T
' Don't serialize a null object, simply return the default for that object
If (Object.ReferenceEquals(orig, Nothing)) Then Return Nothing
Dim formatter As New BinaryFormatter()
Dim stream As New MemoryStream()
formatter.Serialize(stream, orig)
stream.Seek(0, SeekOrigin.Begin)
Return CType(formatter.Deserialize(stream), T)
End Function
これは、クラスからのすべての情報をポータブル オブジェクトにシリアル化し、参照ポインターを切断するためにそれを書き換えることによって機能します。
注: 渡されたクラスと、それがプロパティとして公開するその他のクラス<Serializable()>
を使用するには、マークを付ける必要があります。BinaryFormatter.Serialize
独自のクラスで複製可能なメソッド自体を公開する場合は、メソッドを追加して、次のICloneable
ようにインターフェイスを実装できます。
<Serializable()>
Public Class MyClass : Implements ICloneable
'NOTE - The Account class must also be Serializable
Public Property PersonAccount as Account
Public Property FirstName As String
Function Clone(ByRef orig As MyClass) As MyClass Implements ICloneable.Clone
' Don't serialize a null object, simply return the default for that object
If (Object.ReferenceEquals(orig, Nothing)) Then Return Nothing
Dim formatter As New BinaryFormatter()
Dim stream As New MemoryStream()
formatter.Serialize(stream, orig)
stream.Seek(0, SeekOrigin.Begin)
Return CType(formatter.Deserialize(stream), T)
End Function
End Class
注: ICloneable は、ディープ クローンまたはシャロー クローンを実行しているかどうかを呼び出し元に示さないため、論争の的となっていることに注意してください。実際には、メソッドをクラスに追加できるようにするためにインターフェースは必要ありません。