|
|
連載
.NETで簡単XML
第11回 オブジェクトをXMLでシリアライズ(3)
株式会社ピーデー 川俣 晶
2003/11/22 |
|
今回のサンプル・プログラムについて
今回もサンプル・プログラムは、Visual Basic .NET(以下VB.NET)とC#で記述したものを用意した。VB.NETのサンプルを掲載するとともに、VB.NET、C#それぞれへのサンプルのリンクを張ってあるので、必要に応じてダウンロードしてほしい。開発環境としてはVisual Studio .NET 2003を使用することを前提にしている。
サンプル・プログラムはすべてWindowsアプリケーションとしてプロジェクトを作成後に、フォームのLoadイベントに実行するコードを書き込み、Trace.WriteLineメソッドで結果を出力する。結果の確認は、統合開発環境(IDE)の出力ウィンドウで行う。ただし、クラスだけはフォームのクラス外に別途記述する必要がある。それぞれのソースの先頭には、以下のコードが書かれているものとする。
Imports System.IO
Imports System.Xml.Serialization |
|
VB.NETの場合 |
using System.IO;
using System.Xml.Serialization; |
|
C#の場合 |
はじめに
前回は、System.Xml.Serialization.XmlSerializerクラスを使用した、オブジェクトのシリアライズ入門を解説した。オブジェクトのシリアライズ(シリアル化とも呼ばれる)とは、インスタンスの内容を1列のデータの列に置き換える処理であり、オブジェクトをファイルに保存したり、通信回線で送る際に必要とされる機能である。今回は、System.Xml.Serialization.XmlSerializerクラスを使用したシリアライズについてより深く解説していきたいと思う。
派生クラスを含む配列のシリアライズ
配列も容易にシリアライズできることは、前回の「配列のシリアル化」で解説した。しかし、ここには1つの罠が待ち構えている。オブジェクトの配列を宣言するのは容易であり、配列の要素の型を指定することは可能である。ただし、その配列に入っているオブジェクトの型が、常に「配列の要素の型」として指定された型と一致しているわけではない。もちろん、無関係な型の参照を代入しようとすれば、それはエラーになる。だが、「配列の要素の型」として指定されたクラスに対する派生クラスのインスタンスへの参照を代入することは、エラーにならない正常な使い方のうちである。これは、ポリモーフィズム、多態性と呼ばれるテクニックを使うと、必然的に起こる状況である。しかし、このような配列をそのままシリアライズすることはできない。
例えば、前回の「配列のシリアル化」のサンプル・プログラムに、Personクラスを継承した新しいクラスを追加し、そのクラスのインスタンスを配列に入れるように変更してから実行すると、以下のような例外が発生してしまう。
'System.InvalidOperationException' のハンドルされていない例外が system.xml.dll で発生しました。 |
このような状況に対処するには、XmlArrayItem属性(System.Xml.Serialization.XmlArrayItemAttributeクラス)を使う。次に示すのは、実際にXmlArrayItem属性を使用して、ポリモーフィズムを用いた配列を含むクラスをシリアライズした例である。
まず、シリアライズされる対象となるクラスを見てみよう。これは、ポリモーフィズムを実現するために、継承関係にある3つのクラスと、それらのクラスの配列を含むクラスの、計4クラスから成っている。
Public Class Person
Private m_name As String = "未設定"
Public Property Name() As String
Get
Return m_name
End Get
Set(ByVal Value As String)
m_name = Value
End Set
End Property
End Class
Public Class Child
Inherits Person
Private m_schoolName As String = "未設定"
Public Property SchoolName() As String
Get
Return m_schoolName
End Get
Set(ByVal Value As String)
m_schoolName = Value
End Set
End Property
End Class
Public Class Adult
Inherits Person
Private m_companyName As String = "未設定"
Public Property CompanyName() As String
Get
Return m_companyName
End Get
Set(ByVal Value As String)
m_companyName = Value
End Set
End Property
End Class
Public Class Persons
<XmlArrayItem(Type:=GetType(Child)), _
XmlArrayItem(Type:=GetType(Adult))> _
Public persons(2) As Person
Public Sub SetPersons(ByVal person1 As Person, ByVal person2 As Person, ByVal person3 As Person)
persons(0) = person1
persons(1) = person2
persons(2) = person3
End Sub
Public Sub Dump()
For Each person As Person In persons
System.Diagnostics.Trace.WriteLine(person.Name)
If TypeOf person Is Child Then
System.Diagnostics.Trace.WriteLine(CType(person, Child).SchoolName)
Else
System.Diagnostics.Trace.WriteLine(CType(person, Adult).CompanyName)
End If
Next
End Sub
End Class |
|
サンプル・プログラム1-1:シリアライズの対象となるクラス(VB.NET版/C#版) |
|
|
Insider.NET 記事ランキング
本日
月間