この章では全てのデータの保存(Save()/SaveContents())と読み込み(Restore()/RestoreContents()))について説明します。
このトピックスは以下のセクションを含みます。
IDslSerializable
Dsl やDslDialog に属するオブジェクトはデータを外部ファイルに保存して、後に読み出して処理を続行する機能としてDslSerializer で定義されているIDslSerializableインターフェイスが実装されています。
IDslSerializable インターフェイスには以下の 4つのメソッドが含まれています。
- Save(Object, TextWriter)
子オブジェクトの作成情報を書き出します。作成情報出力後、子オブジェクトに子オブジェクトがあることを 想定して子オブジェクトの Save() メソッドを呼び出します(もちろん子オブジェクトはIDslSerializableを実装している場合です)。 子オブジェクトが存在しない場合は何もする必要はありません。
Processorオブジェクトの場合は登録されているVariableオブジェクトが子オブジェクトとなります。 (書き込まれた作成情報は後のRestore()メソッドで読み込まれると同時に、読み込んだ情報を元に、Variable が作成され Processor に再登録されます)。 Processor は Variable の作成情報を出力した後で Variable の Save() メソッドを呼び出します。
- SaveContents(Object, TextWriter)
自分自身と子オブジェクトのプロパティ値等の情報を出力します。 子オブジェクトが存在する場合、子オブジェクトの SaveContents() メソッドを呼び出します(もちろん子オブジェクトはIDslSerializableを実装している場合です)。
- Restore(Object, TextReader)
子オブジェクトの作成情報を読み込み作成します(Save()の逆)。 作成後、子オブジェクトの Restore() メソッドを呼び出します(もちろん子オブジェクトはIDslSerializableを実装している場合です)。 子オブジェクトが存在しない場合は何もする必要はありません。
- RestoreContents(Object, TextReader)
プロパティ値等を読み込み SaveContents() 呼び出し時の状態に自分自身を戻します。 子オブジェクトが存在する場合、子オブジェクトの RestoreContent() メソッドを呼び出します(もちろん子オブジェクトはIDslSerializableを実装している場合です)。
Save()/Restore() と SaveContents()/RestoreContents()、それぞれ2段構えになっていることに注意してください。 Save()で子オブジェクトの作成情報の書き込み後SaveContents()で自分と子オブジェクトのプロパティ値等を出力、 逆にRestore()で子オブジェクトを全て作成してからRestoreContents()で自分と子オブジェクトを書き込み時の状態に戻します (これは個々の子オブジェクトの状態を元に戻す時に、他のオブジェクトを参照する場合を考慮して、参照対象のオブジェクトの存在を確実にするためです)。
注意事項: |
---|
Restore()では処理の前に Processor に登録された Variable は処理前に一旦全て削除されます。 その後 Restore() 内で再作成されて Processor に再登録されます。 |
注意事項: |
---|
Restore()で再作成された Variable の右辺変数配列、Value や Flag は RestoreContents() で回復されます。 しかし、前に設定された ComputeValueAt 等の delegate は回復されません。 RestoreContents() を override するなり何らかのタイミングを利用して必ず delegate を元に戻す操作を組み込んでください。 |
継承と virtual
Processor や Variable は継承可能です。当然、継承された Variable も Processor に登録できます。 ただ Processor は利用者がどのように Variable を継承するのか知りません。 このことは Restore() で子オブジェクトを作成する場合 new を使用できないことを意味します(new が使用できるのなら「子オブジェクトの作成情報」を書き込む必要もありません)。 DslSerializerでは子オブジェクトの作成情報を得るために ObjectToString(Object) が用意されています。逆に子オブジェクトを文字列から作成するParseObject(String) を利用できます。
継承されたオブジェクトを再作成することは可能ですが、追加されたプロパティ等の値は再設定されません。 Prosessor に実装された IDslSerializer の Save()/Restore() と SaveContents()/RestoreContents() は全て virtual です。 追加したプロパティ等の値を書き出したり読み込んだりする場合は各メソッドを override する必要があります。
以上を考慮すると、Save()/Restore()の処理イメージは以下のようになります。 メソッドの詳細などはDslSerializerを参照してください。
コードをコピー | |
---|---|
// 継承オブジェクトのイメージ. public class MyProcessor: Processor { ............................ public override void Save(object parent, TextWriter sw) { base.Save(parent, sw); // 新たに追加した子ブジェクトの Save() ............................ } public override void SaveContents(object parent, TextWriter sw) { base.SaveContents(parent, sw); // 追加プロパティ値等の出力. ............................ // 新たに追加した子ブジェクトの SaveContents() ............................ } public override void Restore(object parent, TextReader sr) { base.Restore(parent, sr); // 子ブジェクトの Restore() ............................ } public override void RestoreContents(object parent, TextReader sr) { base.RestoreContents(parent, sr); // 追加プロパティ値等の回復 ............................ // 新たに追加した子ブジェクトの SaveContents() ............................ } } public class MyVariable: Variable { ............................ public override void Save(object parent, TextWriter sw) { base.Save(parent, sw); // 新たに追加した子ブジェクトの Save() ............................ } public override void SaveContents(object parent, TextWriter sw) { base.SaveContents(parent, sw); // 追加プロパティ値等の出力. ............................ // 新たに追加した子ブジェクトの SaveContents() ............................ } public override void Restore(object parent, TextReader sr) { base.Restore(parent, sr); // 子ブジェクトの Restore() ............................ } public override void RestoreContents(object parent, TextReader sr) { base.RestoreContents(parent, sr); // 追加プロパティ値等の回復 ............................ // 新たに追加した子ブジェクトの SaveContents() ............................ } } |
コードをコピー | |
---|---|
// Save()/SaveContents() のイメージ. MyProcessor pr = new MyProcessor(); MyVariable v = new MyVariable(pr,"名前"); ................... StremWriter sw = new StreamWriter("ファイルのパス"); pr.Save(this,sw); pr.SaveContents(this,sw); sw.Close(); // Restore()/RestoreContents() のイメージ. ................... StremReader sr = new StreamReader("Save()されたファイルのパス"); pr.Restore(this,sr); pr.RestoreContents(this,sr); sr.Close(); |
注意事項: |
---|
.Net のクラスライブラリィーには XmlSerializer が同様な機能を持っています。 しかし、 XmlSerializer は public な情報だけを扱います。Dsl では private な情報も出力/回復する必要があるため XmlSerializer をサポートしていません。 |