首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >奇怪的反序列化错误,子对象没有完全反序列化。

奇怪的反序列化错误,子对象没有完全反序列化。
EN

Stack Overflow用户
提问于 2011-12-09 11:26:11
回答 2查看 492关注 0票数 3

我刚刚注意到二进制序列化中有一种奇怪的行为:当我在类中反序列化字典并试图立即添加一些内容时,我会得到一个错误,因为它没有完全初始化:

代码语言:javascript
复制
[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属性不是空的:它是实例化的,但不是初始化的(它的所有字段都是0或null)。我怀疑它仅仅是用FormatterServices.GetUninitializedObject创建的,但实际上还没有被反序列化。

我知道,在这一点上,也许它不应该被完全初始化。因此,我尝试了另一种方法,通过实现IDeserializationCallback接口。MSDN说:

实现当前接口作为对对象图反序列化完成时调用的方法的支持的一部分。

如果一个对象需要对它的子对象执行代码,它可以延迟这个操作,实现IDeserializationCallback,并且只有当它在这个接口上被调用时才能执行该代码。

因此,这似乎正是我所需要的,我希望当OnDeserialization被调用时,我的字典会被完全初始化。但我也犯了同样的错误!

代码语言:javascript
复制
[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,它可以正常工作,但不知何故,我认为我不应该这样做…

这种行为正常吗?有人能解释这是怎么回事吗?

EN

回答 2

Stack Overflow用户

发布于 2011-12-11 17:13:03

如果将Dict.OnDeserialization(sender)添加到反序列化处理程序中,那么一切都会变得很好。

因此,这是可行的:

代码语言:javascript
复制
    [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");
        }
    }
票数 1
EN

Stack Overflow用户

发布于 2011-12-09 15:50:42

需要在Dictionary<>处理程序中实例化您的OnDeserialization

代码语言:javascript
复制
public void OnDeserialization(object sender)
{
    Dict = new Dictionary<int, string>();
    Dict.Add(99, "test"); // Error here
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8444788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档