使用ISerializable使用循环引用序列化事件

时间:2014-01-24 21:11:24

标签: c# events serialization circular-reference iserializable

我必须处理序列化一堆对象。为了简单起见,我将[Serializable]属性与二进制序列化器和二进制格式化程序一起使用,排除了大多数内容[NonSerialized]的非必要字段。对于更复杂的部分,我实现了ISerializable接口+反序列化构造函数。即使有了循环引用(以普通对象引用的形式),这也很有效。

现在我发现了一些令我困惑的事情。当一个类B实现ISerializable,并且被另一个类引用(让它命名为Container)订阅该类的事件时,GetObjectData - 方法{{序列化时,1}}被调用两次。

B

所以这个示例代码写了

[Serializable]
class Container
{
    B subObj;
    public int X;
    public event EventHandler E;

    public Container()
    {
        subObj = new B(this);
    }

}

[Serializable]
class B : ISerializable
{
    private Container parent;

    public B(Container parent) {
        this.parent = parent;

        parent.E += (sender, e) => { Console.WriteLine(this.parent.X); };
    }

    protected B(SerializationInfo info, StreamingContext context) { }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        Console.WriteLine("GetObjectData");
    }
}

对于圆形效果的问题,我宁愿预期堆栈溢出或某事:-)。尽管不好。此示例的解决方法当然是在反序列化构造函数中重新添加事件。但是我想要落后于这个原因。

最后一件事:如果将lambda表达式中的引用更改为以下内容(引用参数,而不是字段)...

GetObjectData
GetObjectData

...序列化在第一次parent.E += (sender, e) => { Console.WriteLine(parent.X); }; 执行后立即与SerializationException B +&lt;&gt; c__DisplayClass2未标记为可序列化)发生崩溃。< / p>

为什么(以及有用的解决方法)表示赞赏的任何提示。

0 个答案:

没有答案