最後に、誰かが興味を持っているかどうか、私自身の質問に対する答えがあります。この記事の最後にある例を考えてみましょう。2 つのクラスがあり、そのインスタンスには相互参照が含まれています。このような状況では、両方のインスタンスのデシリアライズ コンストラクターが構築されたオブジェクトと共に渡される可能性はありません。したがって、シリアライザーは最初にコンストラクターの 1 つを呼び出して、2 番目の型の構築されていないインスタンスを渡し、次にそのオブジェクトのコンストラクターを呼び出して、最初の型の構築されたインスタンスを渡します。このように、オブジェクトの接続を復元するのに役立つので、これができるのは本当に最高です!
次に、そのような場合のコールバックは、質問で指摘したように呼び出される可能性がありますがOnDeserializing
、仕様に記載されているとおり、COMPLETE オブジェクト グラフが逆シリアル化された後に常にメソッドが呼び出されます。OnDeserialized
OnDeserialization
IDeserializationCallback
上記のすべてを念頭に置いて、IDeserializationCallback
インターフェイスを使用して、必要なデシリアライゼーション後の処理を行うのが最善だと思います。その場合、すべてのオブジェクトに対してコンストラクターが呼び出され、必要な変更を「安全な」方法で行うことができると確信しています。
[Serializable]
class One :ISerializable, IDeserializationCallback
{
public Two m_two;
public One() {}
public One(SerializationInfo info, StreamingContext context)
{
var two = (Two)info.GetValue("m_two", typeof(Two));
m_two = two;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("m_two", m_two);
}
private bool m_onDeserializing;
private bool m_onDeserialized;
private bool m_callback;
public void OnDeserialization(object sender)
{
m_callback = true;
}
[OnDeserializing]
void OnDeserializing(StreamingContext context)
{
m_onDeserializing = true;
}
[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
m_onDeserialized = true;
}
}
[Serializable]
private class Two : ISerializable, IDeserializationCallback
{
public Two(){}
public One m_one;
public Two(SerializationInfo info, StreamingContext context)
{
var one = (One)info.GetValue("m_one", typeof(One));
m_one = one;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("m_one", m_one);
}
private bool m_onDeserializing;
private bool m_onDeserialized;
private bool m_callback;
public void OnDeserialization(object sender)
{
m_callback = true;
}
[OnDeserializing]
void OnDeserializing(StreamingContext context)
{
m_onDeserializing = true;
}
[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
m_onDeserialized = true;
}
}
[STAThread]
static void Main()
{
var one = new One();
one.m_two = new Two();
one.m_two.m_one = one;
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream mss =new MemoryStream();
formatter.Serialize(mss, one);
mss.Position = 0;
var deserialize = formatter.Deserialize(mss);
}