クラスや構造体などのオブジェクトのクローンコピーを作りたい場合があります。 各種のオブジェクトのデータを退避する時に、一括でクローンが作れれば便利なのですが、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
コメント