1

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

现在我偶然发现了一些让我有点困惑的东西。当一个类B实现ISerializable,并且被另一个类引用(让我们命名它Container)订阅该类的事件时,序列化时恰好调用了两次GetObjectData-Method 。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");
    }
}

所以这个示例代码写

GetObjectData
GetObjectData

对于循环效果的问题,我宁愿期待堆栈溢出或其他东西:-)。总之不好。此示例的解决方法当然是在反序列化构造函数中重新添加事件。但我想了解造成这种情况的原因。

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

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

...序列化在第一次执行后立即崩溃SerializationExceptionB+<>c__DisplayClass2 未标记为 Serializable )。GetObjectData

任何有关原因(以及有用的解决方法)的提示都表示赞赏。

4

0 回答 0