クラスや構造体などのオブジェクトのクローンコピーを作りたい場合があります。 各種のオブジェクトのデータを退避する時に、一括でクローンが作れれば便利なのですが、BinaryFormatter クラスを 使って、シリアライズとデシリアライズを行うことでできます。
以下のソースにその関数を記します。 BinaryFormatter の Serialize メソッドによりコピー元のオブジェクトをメモリストリームに展開します。 その後メモリストリームの内容を別のオブジェクトにデシリアライズを行います。
ディープコピー関数
''' -----------------------------------------------------------------------
'''
''' オブジェクトのコピー
'''
''' Type
''' <param name="objSrc">コピー元のオブジェクト</param>
''' クローンオブジェクト
''' -----------------------------------------------------------------------
Function DeepCopy(Of T)(ByVal objSrc As T) As T
'クローンオブジェクト宣言
Dim objRet As T
'BinaryFormatterクラス
Dim b As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
'バイト処理を行うメモリストリーム
Dim ms As New System.IO.MemoryStream()
Try
'シリアライズ(MemoryStreamにシリアライズ化して展開)
b.Serialize(ms, objSrc)
'メモリ位置を初期化
ms.Position = 0
'デシリアライズ(MemoryStreamからデシリアライズ化してオブジェクトに戻す)
objRet = CType(b.Deserialize(ms), T)
Catch ex As Exception
'
Finally
ms.Close()
End Try
'クローンを戻す
Return objRet
End Function
この関数を使う例を以下に記します。
以下のソースでは、 DeepCopy 用のテストクラスとして clsCopyTest と、 テスト構造体として structCopyTest を宣言しています。
それぞれのクラス、構造体ともに <Serializable()> を指定しています。 これが無いとシリアライズ処理ができないので注意が必要です。
ディープコピー関数の使用例
'''''' DeepCopy 用のテストクラス ''' <Serializable()> _ Private Class clsCopyTest Public _strTest As String Public _intTest As Integer 'コンストラクタ Sub New(ByVal strTest As String, ByVal intTest As Integer) Me._strTest = strTest Me._intTest = intTest End Sub '内部データの表示用の文字列取得 Function GetDataString() As String Return "strTest=" & Me._strTest & vbCrLf & "intTest=" & Me._intTest.ToString End Function End Class '''''' DeepCopy 用のテスト構造体 ''' <Serializable()> _ Private Class structCopyTest Private _strTest As String Private _intTest As Integer 'コンストラクタ Sub New(ByVal strTest As String, ByVal intTest As Integer) Me._strTest = strTest Me._intTest = intTest End Sub '内部データの表示用の文字列取得 Function GetDataString() As String Return "strTest=" & Me._strTest & vbCrLf & "intTest=" & Me._intTest.ToString End Function End Class Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'クラスでのテスト Dim clsT As New clsCopyTest("ABCD", 100) 'クラス生成 Dim clsCloneT As clsCopyTest = DeepCopy(clsT) 'クラスクローンコピー clsCloneT._strTest &= "..." 'クローンのデータを更新 clsCloneT._intTest *= 100 'クラスのメソッドで内容表示 MsgBox("Src :" & vbCrLf & clsT.GetDataString & vbCrLf & "Clone:" & vbCrLf & clsCloneT.GetDataString) '構造体でのテスト Dim strucT As New structCopyTest("EFGHI", 200) '構造体生成 Dim strucCloneT As structCopyTest = DeepCopy(strucT) '構造体クローンコピー MsgBox(strucCloneT.GetDataString) '構造体のメソッド End Sub
ボタン処理内でクラスのテストと、構造体のテストを行っています。 クラスの方は、クローンコピーの値を少し変化を加えています。 その後、それぞれのクラス内の値を見てみると、両方の値が異なることが分かります。
関連する記事
⇒クラスのコピーについて(Object.MemberwiseClone)PR
コメント