我必须处理序列化一堆对象。为了简单起见,我将[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>
为什么(以及有用的解决方法)表示赞赏的任何提示。