我刚刚注意到二进制序列化中的一个奇怪行为:当我在我的类中反序列化一个字典并尝试立即向其中添加一些内容时,我收到一个错误,因为它没有完全初始化:
[Serializable]
class Foo : ISerializable
{
public Dictionary<int, string> Dict { get; private set; }
public Foo()
{
Dict = new Dictionary<int, string>();
}
public Foo(SerializationInfo info, StreamingContext context)
{
Dict = (Dictionary<int, string>)info.GetValue("Dict", typeof(Dictionary<int, string>));
Dict.Add(99, "test"); // Error here
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Dict", Dict);
}
}
在我向字典中添加数据的那一行,我得到一个
NullReferenceException
,但 Dict
property 不为 null:已实例化,但未初始化(其所有字段均为 0 或 null)。我怀疑它只是用 FormatterServices.GetUninitializedObject
创建的,但实际上还没有反序列化。我知道在这一点上,也许它不应该被完全初始化。所以我尝试了另一种方法,通过实现
IDeserializationCallback
界面。 MSDN 说:Implement the current interface as part of support for a method that is called when deserialization of the object graph is complete.
If an object needs to execute code on its child objects, it can delay this action, implement IDeserializationCallback, and execute the code only when it is called back on this interface
所以这似乎正是我所需要的,我希望我的字典在
OnDeserialization
时被完全初始化。被称为......但我得到同样的错误![Serializable]
class Foo : IDeserializationCallback
{
public Dictionary<int, string> Dict { get; private set; }
public Foo()
{
Dict = new Dictionary<int, string>();
}
public void OnDeserialization(object sender)
{
Dict.Add(99, "test"); // Error here
}
}
由于
IDeserializationCallback
旨在对子对象执行代码,我希望此时子对象已完全初始化。请注意,如果我调用 OnDeserialize
手动在字典上,它工作正常,但不知何故我不认为我应该这样做......这种行为正常吗?谁能解释这里发生了什么?
最佳答案
如果添加 Dict.OnDeserialization(sender)
到您的反序列化处理程序,然后一切都会好起来的。
所以,这有效:
[Serializable]
class Foo : IDeserializationCallback
{
public Dictionary<int, string> Dict { get; private set; }
public Foo()
{
Dict = new Dictionary<int, string>();
}
public void OnDeserialization(object sender)
{
// The dictionary is initialized with values in next line
Dict.OnDeserialization(sender);
Dict.Add(99, "test");
}
}
关于.net - 奇怪的反序列化错误,子对象没有完全反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8444788/