6

シリアル化されたオブジェクト グラフのツリー/ビューを作成できる方法があるかどうか、また誰かがポインターを持っているかどうか疑問に思っています。編集目的は、何らかの理由で逆シリアル化の問題が発生した場合に、シリアル化されたデータに関するレポートを実際に表示/生成して、コードをデバッグする前に問題の原因を特定できるようにすることです。さらに、将来的にはこれを拡張して 2 つのストリーム (バージョン 1、バージョン 2) を取得し、2 つのストリームの違いを強調して、コードの変更中に興味深い情報を誤って削除しないようにしたいと考えています。/編集

従来は Soap または XML シリアライゼーションを使用してきましたが、これらは制限が強すぎてニーズが満たされなくなってきており、通常はバイナリ シリアライゼーションが必要なすべてを実行します。これが採用されなかった理由は、シリアル化されたコンテンツを表示してアップグレードの問題などを修正するのが非常に難しいためです。

そのため、シリアル化された情報に関するビューを作成することを検討し始めました。ISerializable コンストラクターからある程度までこれを行うことができます。

public A(SerializationInfo info, StreamingContext context)
{}

シリアル化情報があれば、m_data メンバーを反映​​して、実際のシリアル化されたコンテンツを確認できます。このアプローチの問題は、

  1. ツリーのブランチのみが表示されます。ルートからツリー全体を表示したいのですが、この位置からは実際にはできません。
  2. 情報を調べるのに便利な場所ではありません。ストリームをクラスに渡して、そこで作業を行いたいと思います。

ObjectManager クラスを見てきましたが、これは既存のオブジェクト グラフで動作しますが、データ ストリームから動作できるようにする必要があります。私は、ObjectReader と __BinaryParser を使用する BinaryFormatted を調べ、ObjectManager にフックします (これにより、コンテンツ全体がフラット リストに含まれることになると思います) が、これを複製するか、リフレクションを介してすべてを呼び出します (2これらの 3 つのクラスの内部) はかなりの作業のように思えるので、より良いアプローチがあるかどうか疑問に思っています。

4

2 に答える 2

0

あなたが説明したことを達成するには、オブジェクトグラフ全体をストリームから逆シリアル化する必要があります。シリアル化された型を知らなくてもかまいません。ただし、シリアライザーはそのような情報を保存しないため、これは不可能です。私の知る限り、それは次のように機能します。いくつかのタイプがあるとします。

class A { bool p1 }
class B { string p1; string p2; A p3}
// instantiate them:
var b = new B { p1 = "ppp1", p2 = "ppp2", p3 = new A { p1 = true} };

シリアライザーがこのオブジェクトを書き込んでいるときに、オブジェクト グラフを特定の順序 (アルファベット順と仮定します) で歩き始め、オブジェクト タイプを書き込んでから内容を書きます。したがって、バイナリ ストリームは次のようになります。

[B:[string:ppp1][string:ppp2][A:[bool:true]]]

ご覧のとおり、ここには値とその型しかありません。しかし、書かれているように、順序は暗黙的です。したがって、オブジェクト B を変更すると、

class B { A p1; string p3; string p3;}

シリアライザーは、(最初にシリアライズされた) 文字列のインスタンスを A へのポインターに割り当てようとするため、失敗します。しかし、これにはかなりの労力が必要になります。

この目的のために、次のようなクラスを作成します。

class Node
{
    public string NodeType;
    public List<Node> Children;
    public object NodeValue;
}

次に、ストリームから読み取っている間に、それらのノードを作成し、シリアル化されたツリー全体を再作成して分析できます。

于 2011-11-10T13:49:35.070 に答える