10

Hashtableへの参照を維持し、そのHashtableをシリアライズ/デシリアライズするクラスがあります。SerializationInfo.GetValue の呼び出し後、IDeserialization のカルバック中に逆シリアル化が発生するため、Hashtable は完全には逆シリアル化されません。

Hashtable hashtable = (Hashtable) info.GetValue("hash", typeof(Hashtable));

親クラスに IDeserialization コールバックも実装しましたが、ハッシュテーブルもまだ完全に逆シリアル化されていません。逆シリアル化が裏返しに行われている場合は、そうなると予想していました。

私の質問は、親クラスの OnDeserialization メソッドから Hashtable.OnDeserialization を明示的に呼び出して、その時点で列挙できるようにしても安全ですか?

public virtual void OnDeserialization(object sender)
{
    hashtable.OnDeserialization(sender);
}
4

2 に答える 2

6

これは実に興味深い問題です。Reflectorでシリアル化コードを確認したところ、参照されるクラスがIDeserializationCallbackを使っている場合、一般的に良い解決策はないと思います。

おそらく、[OnDeserializing] 属性と [OnDeserialized] 属性を使用して、逆シリアル化中にコードを実行する方法が 2 つあることをご存知でしょう。残念ながら、どちらも IDeserializationCallback.OnDeserialization() の前に実行されます。これは、class2 を参照する class1 がある場合のメソッドの実行順序です。

Class1: [OnDeserializing]
Class2: [OnDeserializing]
Class2: [OnDeserialized]
Class1: [OnDeserialized]
Class1: IDeserializationCallback.OnDeserialization
Class2: IDeserializationCallback.OnDeserialization

ご覧のとおり、[OnDeserializing] 属性と [OnDeserialized] 属性は一貫して機能しますが、IDeserializationCallback メソッドは実際にはそうではありません... :(

Hashtable と Dictionary の OnDeserialization 実装も確認しましたが、どちらも OnDeserialization を複数回呼び出しても安全であるようです (最初の呼び出しのみが必要な操作を実行し、後続の呼び出しは何もしません)。

Seanと Brian が提案したように、最後に Hashtable の OnDeserialization() を呼び出す必要があります。

于 2008-11-19T10:13:33.623 に答える
3

すでにググったことがあると思いますが、昨日たまたまこのパターンに出会いました。

public BoringClass(SerializationInfo info, StreamingContext context)
{
    Hashtable hashtable = (Hashtable) info.GetValue("hash", typeof(Hashtable));
    hashtable.OnDeserialization(this);

    Console.WriteLine("Value is: " + hashtable["testItem"]);

}
于 2008-11-13T19:02:51.000 に答える