我正在編寫我自己的IFormatter實現,我想不出一種方法來解決實現ISerializable的兩種類型之間的循環引用。解決實現ISerializable的對象的循環引用
下面是通常的模式:
[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序列化並deserialise B,上述測試正如人們所期望的那樣,引用相等返回true。但我無法想象在我的自定義IFormatter中實現這一點的方法。
在非ISerializable的情況下,我可以簡單地在解決目標引用後使用反射重新訪問「待處理」對象字段。但是對於實現ISerializable的對象,使用SerializationInfo注入新數據是不可能的。
任何人都可以指向正確的方向嗎?
我明白你關於「參考標籤」的觀點,我的格式化工具已經使用了這種技術。因此你的自引用例子對我來說不是問題。但是我沒有看到你的答案如何幫助我實現可互相引用的ISerializable-實現對象。你能解決這個具體問題嗎?謝謝。 – Chris 2010-04-26 10:55:29
不完全確定你的意思。你在談論使用與序列化相關的私有構造函數嗎? – 2010-04-26 10:56:20
是的,確切地說。膨脹實現ISerializable的對象的唯一方法是調用它的特殊構造函數。 – Chris 2010-04-26 11:01:27