DOBON.NET DOBON.NETプログラミング掲示板過去ログ

コンストラクタを持つクラスのオブジェクトをアイテムとして持つArrayListのXmlシリアライズ化について

環境/言語:[Windows Xp, VisualStudio.NET , .NET Framework1.0]
分類:[.NET]

初めて投稿しますnissa.comです。

.Net Tipsのファイル関連のセクションにある、
ArrayListのXmlシリアライズ化を参考に、
自分でもArrayListをXmlシリアライズ化するプログラムをC#で組んでる途中で問題が発生しました。

シリアライズ化するArrayListは以下のようなクラスのオブジェクトをアイテムとして持ちます。

public class MemberData
{
public string Account;
public string URL;

public MemberData(string ac, string url)
{
this.Account = ac;
this.URL = url;
}
}

このクラスのオブジェクトをアイテムとして持つArrayList(名前:MemberList)を、変数として持つMemberというクラスを、
Tipsにあったように、
System.Xml.Serialization.XmlSerializer serializer =
new System.Xml.Serialization.XmlSerializer(typeof(Member));
…という風にしてデバッグすると、コンパイルは通るものの、
上記serializerインスタンス生成の段階で、
『System.InvalidException:MemberDataに既定のパブリックコンストラクタが組み込まれていないためシリアライズ化できませんでした』というエラーが発生してしまいます。

色々試してみた結果、
MemberDataの2つの変数の内容を、コンストラクタではなく、
インスタンス生成後に、
呼び出したクラスの中で別途設定するようにすれば、シリアライズ化することができたのですが、
なぜコンストラクタを用いるといけないのでしょうか?

ググってみたり、MSDNを検索してみたのですが、
コンストラクタについての記述は見つかるのですが、どうも理由を示すような記事を見つけることができませんでした。
コンストラクタもpublicと明示的にしてるし…。

このようなわけなので、問題自体は解決しているのですが、
オブジェクト指向プログラミングを勉強中の身としては、
やはりコンストラクタで設定すべき変数はコンストラクタでやるべきではないか…と感じ、
質問させていただきました。

急ぎの質問ではありません。
コンストラクタを持つクラスのオブジェクトを、
アイテムとして持つようなArrayListのシリアライズ化をする際は特別な手続きが必要なのか、
必要ならばそれはどのような手続きなのか、
教えていただけたらと思います。
> このクラスのオブジェクトをアイテムとして持つArrayList(名前:MemberList)を、変数として持つMemberというクラスを、
> Tipsにあったように、
> System.Xml.Serialization.XmlSerializer serializer =
> new System.Xml.Serialization.XmlSerializer(typeof(Member));
> …という風にしてデバッグすると、コンパイルは通るものの、
> 上記serializerインスタンス生成の段階で、
> 『System.InvalidException:MemberDataに既定のパブリックコンストラクタが組み込まれていないため
> シリアライズ化できませんでした』というエラーが発生してしまいます。

既定のコンストラクタとは引数なしのコンストラクタのことですが、
それがないからですね。

> 色々試してみた結果、
> MemberDataの2つの変数の内容を、コンストラクタではなく、
> インスタンス生成後に、
> 呼び出したクラスの中で別途設定するようにすれば、シリアライズ化することができたのですが、
> なぜコンストラクタを用いるといけないのでしょうか?

シリアライズされたオブジェクトは、後で使用するときデシリアライズしないと
いけないわけですが、このときにリフレクションを使用し、既定のコンストラクタを
使ってインスタンスを生成するためです。

デシリアライズする機構からすれば、引数つきのコンストラクタでインスタンスを
生成しようにもその引数に何を渡せばいいかわからないので、
引数つきのコンストラクタではインスタンスの生成ができません。
よねKENさん、回答ありがとうございました。

> 既定のコンストラクタとは引数なしのコンストラクタのことですが、
> それがないからですね。
>
> シリアライズされたオブジェクトは、後で使用するときデシリアライズしないと
> いけないわけですが、このときにリフレクションを使用し、既定のコンストラクタを
> 使ってインスタンスを生成するためです。
>
> デシリアライズする機構からすれば、引数つきのコンストラクタでインスタンスを
> 生成しようにもその引数に何を渡せばいいかわからないので、
> 引数つきのコンストラクタではインスタンスの生成ができません。
なるほど…。
大変参考になりました。胸のつかえが取れた感じです。
どうもありがとうございました。

DOBON.NET | プログラミング道 | プログラミング掲示板