私は独自の IFormatter 実装を作成していますが、両方とも ISerializable を実装する 2 つの型の間の循環参照を解決する方法が思いつきません。
通常のパターンは次のとおりです。
[Serializable]
class Foo : ISerializable
{
private Bar m_bar;
public Foo(Bar bar)
{
m_bar = bar;
m_bar.Foo = this;
}
public Bar Bar
{
get { return m_bar; }
}
protected Foo(SerializationInfo info, StreamingContext context)
{
m_bar = (Bar)info.GetValue("1", typeof(Bar));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("1", m_bar);
}
}
[Serializable]
class Bar : ISerializable
{
private Foo m_foo;
public Foo Foo
{
get { return m_foo; }
set { m_foo = value; }
}
public Bar()
{ }
protected Bar(SerializationInfo info, StreamingContext context)
{
m_foo = (Foo)info.GetValue("1", typeof(Foo));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("1", m_foo);
}
}
次に、これを行います。
Bar b = new Bar();
Foo f = new Foo(b);
bool equal = ReferenceEquals(b, b.Foo.Bar); // true
// Serialise and deserialise b
equal = ReferenceEquals(b, b.Foo.Bar);
すぐに使用できる BinaryFormatter を使用して b をシリアル化および逆シリアル化すると、上記の参照等価性のテストは予想どおり true を返します。しかし、カスタム IFormatter でこれを実現する方法が思いつきません。
ISerializable でない状況では、ターゲット参照が解決されたら、リフレクションを使用して「保留中」のオブジェクト フィールドに簡単に再アクセスできます。ただし、ISerializable を実装するオブジェクトの場合、SerializationInfo を使用して新しいデータを挿入することはできません。
誰かが私を正しい方向に向けることができますか?