ようこそ。睡眠不足なプログラマのチラ裏です。

System.Windows.Forms.Formの派生クラスをシリアライズしてみる

画面オブジェクト(System.Windows.Forms.Formの派生クラス)の、
特定のプロパティをシリアル化してXMLに保存したり読み込んだりする機能について、必要に迫られました。
特定のプロパティを抽出してSerializableなクラスをつくり、それを画面オブジェクトのメンバに持たせて、
そのメンバをシリアライズするという手法をとろうかと最初は考えていたのですが、
どうもカッコ悪い(´Д`;)ということで、他の方法について調べてみました。
どうやらカスタムシリアル化ってのをやると良いらしいです。


カスタムシリアル化


オブジェクトの ISerializable インターフェイスをインプリメントすることで、
シリアル化 プロセスをカスタマイズすることができます。これは、逆シリアル化の後に
メンバ変数の値が無効になるが、オブジェクトの完全な状態を再構築するためには
変数に値を与えなくてはならないようなケースで特に便利です。ISerializable をインプリメントするためには、
GetObjectData メソッドと、オブジェクトが逆シリアル化されるときに使用される特殊なコンストラクタ
インプリメントする必要があります。次のサンプル コードは、前のセクションの
MyObject クラスの ISerializable をインプリメントする方法を示しています。

///[C#]

[Serializable]
public class MyObject : ISerializable
{
 public int n1;
 public int n2;
 public String str;

 public MyObject()
{
 }

 protected MyObject(SerializationInfo info, StreamingContext context)
 {
  n1 = info.GetInt32("i");
  n2 = info.GetInt32("j");
  str = info.GetString("k");
 }

 public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
 {
  info.AddValue("i", n1);
  info.AddValue("j", n2);
  info.AddValue("k", str);
 }
}


ということで、ISerializableインターフェイスを実装しつつ、属性を付加して、
SoapFormatterを使って対象オブジェクトをシリアライズすると、万々歳ということでした。
ただし、画面オブジェクト(System.Windows.Forms.Formの派生クラス)自身にXMLをデシリアライズするメソッドを
実装する様な場合、System.Reflectionを利用して自身のプロパティに反映させるという
手順を踏む必要があるので、少し手間に感じるかもしれません。その点においては、
この方法はスマートとは言えない気がします。が、結構使えるなーとも思いましたのでメモメモ。


オマケ
ISerializableインターフェイスを使ってみる(カスタムシリアル化) - VB.NET - 雑なサンプルソース