I am writing my own implementation of IFormatter, and I cannot think of a way to solve circular references between two types that implement ISerializable.
Here's a regular template:
[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);
}
}
Then I will do the following:
Bar b = new Bar();
Foo f = new Foo(b);
bool equal = ReferenceEquals(b, b.Foo.Bar);
equal = ReferenceEquals(b, b.Foo.Bar);
If I use the ready-made BinaryFormatter to serialize and deserialize b, the above test for reference equality returns true, as expected. But I can’t imagine a way to achieve this in my usual IFormatter.
In a non-ISerializable situation, I can simply revise the “pending” fields of the objects using reflection when the target links were resolved. But for objects that implement ISerializable, it is not possible to enter new data using SerializationInfo.
- ?