XMLシリアライズできないケースに対応する。循環参照に対応する。
■循環参照
System.InvalidOperationException はハンドルされませんでした。
Message="XML ドキュメントを生成中にエラーが発生しました。"
オブジェクトのシリアル化を実行中に循環参照が見つかりました。
上記のようなエラーは、シリアライズを行うインスタンスに循環参照が存在するためだ。具体的には次のようなインスタンスはシリアライズに失敗する。
_
Public Class TreeItem
Public Name As String
Public ParentItem As TreeItem
Public Childs As New List(Of TreeItem)
End Class
TreeItemは、ChildsコレクションによってTreeItemを所有する階層構成を持つ一般的なクラスだが、ParentItemプロパティによって親階層への参照を保持している。
これが循環参照を引き起こしている。
循環参照は実データではなく参照データなので、シリアライズ対象とするのに適さない。
・
_
Public ParentItem As TreeItem
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Xml.Serialization
_
Public Class TreeItem
Public Name As String
_
Public ParentItem As TreeItem
Public Childs As New List(Of TreeItem)
End ClassPublic Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim item As New TreeItem
item.Name = "root"
Dim child As New TreeItem
child.Name = "child"
child.ParentItem = itemitem.Childs.Add(child)
Dim child2 As New TreeItem
child2.Name = "aaaa"
child.Childs.Add(child2)
Dim serializer As New XmlSerializer(GetType(TreeItem))
Dim sw As New StreamWriter("c:\xml.txt")
serializer.Serialize(sw, item)
sw.Close()
End Sub
End Class
root
child
aaaa
シリアライズ・デシリアライズで循環参照を取り扱いたいなら、シリアライズ以外の方法で対処する必要がある。例えば、オブジェクトごとにシーケンスIDを付与してIDからオブジェクトを再起呼び出しで検索するようなメソッドを作る方法がその一つだ。