.NETで構造体をメンバ配列の値を含めてコピーしたい。件
VB6からVB.NETへの変更時にちょっとはまったのでメモ。
元の処理の簡略化イメージ
構造体の配列へいろいろ計算した結果をどんどんためていく処理がある。
'構造体定義 Public Structure ST Dim int01 As Integer Dim aInt01 As Integer() Public Sub New(x As Integer) ReDim aInt01(10) End Sub End Structure '値のセット Dim arraySt1(9) As ST Dim iST As ST = New ST(0) For i = 0 To 9 iST.int01 = i iST.aInt01(0) = i arraySt1(i) = iST Next
構造体STの配列arraySt1(n)に構造体X型の変数iSTの値を変えながら単純にコピーしている。
構造体は値型なのでarratSt1(n).int01は問題なくセットされるが、
arraySt1(n).aInt01(0)は最後にセットした9ですべて上書きされていた。
構造体は値型でもメンバが参照型の場合は参照先のアドレスが値として入ってるだけなんですよね。。
解決策を検討(ググって)していると
どんなオブジェクトでもコピーできる汎用のディープコピー処理
なんてのがあったので、ありがたくリスペクトさせいただきました。
今回はVB.NETのジェネリック版のみなので以下のように定義
Imports System.Runtime.Serialization.Formatters.Binary Imports System.Runtime.CompilerServices Public Class CommonUtil Public Shared Function ObjCopy(Of T)(ByVal target As T) As T Dim CopyObj As T Dim BF As New BinaryFormatter Using MemStream As New System.IO.MemoryStream() BF.Serialize(MemStream, target) MemStream.Position = 0 CopyObj = CType(BF.Deserialize(MemStream), T) End Using Return CopyObj End Function End Class
元のソースをちょっと修正して期待通りの動作となりました。
'構造体定義 <Serializable()> _ '★追加 Public Structure ST Dim int01 As Integer Dim aInt01 As Integer() Public Sub New(x As Integer) ReDim aInt01(10) End Sub End Structure 値のセット Dim arraySt1(9) As ST Dim iST As ST = New ST(0) For i = 0 To 9 iST.int01 = i iST.aInt01(0) = i arraySt1(i) = CommonUtil.ObjCopy(iST) '★変更 Next
めでたしめでたし。