我必须处理序列化一堆对象。为了简单起见,我将[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); };
...序列化在第一次执行后立即崩溃SerializationException
(B+<>c__DisplayClass2 未标记为 Serializable )。GetObjectData
任何有关原因(以及有用的解决方法)的提示都表示赞赏。