正如 MSDN 所说here http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx, 它可以。
但我花了 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 在其他几个地方的构造函数之前被调用,所以我现在很害怕它不是很可靠......
Thanks!
最后,我自己的问题有了答案,如果有人感兴趣的话。
考虑本文末尾的示例。有两个类,它们的实例包含彼此的引用。在这种情况下,两个实例的反序列化构造函数不可能与构造对象一起传递。因此,序列化器首先调用一个构造函数,向其传递第二类型的未构造实例,然后调用该对象的构造函数,向其传递第一类型的构造实例。通过这种方式,它可以帮助我们恢复对象连接,所以它确实是它能做到的最好的!
Next, OnDeserializing
and OnDeserialized
在这种情况下的回调可能会像我在问题中指出的那样被调用,而OnDeserialization
的方法IDeserializationCallback
总是在 COMPLETE 对象图被反序列化之后调用,正如其规范中所述。
记住以上所有内容,我发现它是最好的使用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);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)