正如MSDN所说的here,它是可以的。但是我花了2个小时来研究mscorlib代码,因为在某些情况下,BinaryFormatter在反序列化构造函数之前调用了我标记为OnDeserialized的方法。也就是说,命令是
OnDeserializing(StreamingContext context)
OnDeserialized(StreamingContext context)
.ctor(SerializationInfo info, StreamingContext context)当我期待它的时候
OnDeserializing(StreamingContext context)
.ctor(SerializationInfo info, StreamingContext context)
OnDeserialized(StreamingContext context)最后一点。当我实现IDeserializationCallback接口时,它的方法OnDeserialization是在构造函数之后调用的,正如我所希望和期望的那样。
我试着在一些简单的类结构上重现这一点,但一切都很好。在我们的项目中,序列化的对象图非常复杂,所以我不知道从哪里去挖掘。用反射器检查mscorlib代码没有多大帮助-反序列化代码太复杂了,我找不出问题的来源。
那么,有没有人知道是什么导致了这样的问题?我们在其他几个地方使用了OnDeserialized在构造函数之前被调用的假设,所以我现在害怕它不是很可靠……
谢谢!
发布于 2012-01-16 19:28:53
最后,我有我自己问题的答案,如果有人感兴趣的话。考虑这篇文章末尾的例子。有两个类,它们的实例包含对彼此的引用。在这种情况下,两个实例的反序列化构造函数都不可能与构造的对象一起传递。因此,序列化程序首先调用其中一个构造函数,向其传递第二种类型的未构造实例,然后调用该对象的构造函数,将其传递给第一种类型的构造实例。在这种情况下,它可以帮助我们恢复对象连接,所以它真的是最好的了!
接下来,正如我在问题中指出的那样,在这种情况下可能会调用OnDeserializing和OnDeserialized回调,而IDeserializationCallback的OnDeserialization方法总是在完整对象图被反序列化之后调用的,正如其规范中所述。
考虑到以上所有内容,我发现最好使用IDeserializationCallback接口来完成我需要的任何反序列化处理。在这种情况下,我确信所有对象都调用了构造函数,并且我可以以一种“安全”的方式进行必要的修改。
[Serializable]
class One :ISerializable, IDeserializationCallback
{
public Two m_two;
public One() {}
public One(SerializationInfo info, StreamingContext context)
{
var two = (Two)info.GetValue("m_two", typeof(Two));
m_two = two;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("m_two", m_two);
}
private bool m_onDeserializing;
private bool m_onDeserialized;
private bool m_callback;
public void OnDeserialization(object sender)
{
m_callback = true;
}
[OnDeserializing]
void OnDeserializing(StreamingContext context)
{
m_onDeserializing = true;
}
[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
m_onDeserialized = true;
}
}
[Serializable]
private class Two : ISerializable, IDeserializationCallback
{
public Two(){}
public One m_one;
public Two(SerializationInfo info, StreamingContext context)
{
var one = (One)info.GetValue("m_one", typeof(One));
m_one = one;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("m_one", m_one);
}
private bool m_onDeserializing;
private bool m_onDeserialized;
private bool m_callback;
public void OnDeserialization(object sender)
{
m_callback = true;
}
[OnDeserializing]
void OnDeserializing(StreamingContext context)
{
m_onDeserializing = true;
}
[OnDeserialized]
void OnDeserialized(StreamingContext context)
{
m_onDeserialized = true;
}
}
[STAThread]
static void Main()
{
var one = new One();
one.m_two = new Two();
one.m_two.m_one = one;
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream mss =new MemoryStream();
formatter.Serialize(mss, one);
mss.Position = 0;
var deserialize = formatter.Deserialize(mss);
}https://stackoverflow.com/questions/4023644
复制相似问题