反序列化一个对象时,某个值未被反序列化。

3
这是我的课程:
namespace myclass
{
    [Serializable]
    public class BasicGameObject : GameObject
    {
      protected Shadow shadow_ = null;
      protected bool shadow_enabled_ = false;

      protected Dictionary<string, AnimationManager> animations_ = new Dictionary<string, AnimationManager>();
      protected Dictionary<string, string> loaded_textures_ = new Dictionary<string, string>();

      protected string current_animation_;

      protected int frame_width_;
      protected int frame_height_;

//Costructor and other methods
//...

    [OnDeserialized]
    private void OnDeserialized(StreamingContext context)
    {
        Console.WriteLine("BasicGameObject");
        foreach (KeyValuePair<string, AnimationManager> anim in animations_)
        {
            animations_[anim.Key].Reload(Loader.GameObjectTexturesList[loaded_textures_[anim.Key]]);
        }
    }

当我反序列化这个对象时,我需要重新加载存储在“animations_”中的每个纹理。如果我在Console.WriteLine("BasicGameObject");上设置断点,并点击anim,调试器会显示animCount为0,但其他所有变量都具有正确的值。(我确定在保存时它不是0)
问题出在哪里?
如何加载对象(SERIALIZATIONOBJECT_仅包含BasicGameObject列表):
    IFormatter formatter = new BinaryFormatter();
    SERIALIZATIONOBJECT_ = (SerializationObject)formatter.Deserialize(stream);
    stream.Close();

在这之后(以及 OnDeserialized 调用之后!),如果我进行一些测试,我会发现对象的 anim 具有正确的值。为什么是在这里而不是在 "OnDeserialized" 里面呢?
我只想指出,在这之前,我使用了相同的函数,现在它在 OnDeserialized 中,没有属性,只是一个函数,在反序列化之后调用它。我看到了自动化的可能性,认为这很好。也许它隐藏了一些东西。

AnimationManager标记为可序列化了吗?如果还没有,您可能需要将其标记为可序列化。 - TyCobb
1
我不确定,但我认为序列化只影响公共属性。 - superarce
2个回答

2
XmlSerializer只能序列化和反序列化公共字段和属性。
参见MSDN文档

XML序列化是将对象的公共属性和字段转换为序列格式(在本例中为XML)以进行存储或传输的过程。[...]

在这种情况下,您可能想要使用数据传输对象(DTO)。 DTO是一个内部类,它作为公共字段或属性保存您的游戏对象的所有数据,可以进行序列化和反序列化。然后,将DTO聚合到游戏对象中,并通过DTO访问数据。

也许我漏掉了什么,但我没有使用XML序列化,而是二进制格式化程序...当我打开输出文件时,我看到一些单词,但很多未知的符号,而不是典型的XML代码。 - Francesco Bonizzi
@misiMe 抱歉,是我不好。我会留下这个答案,并发布另一个关于 OnDeserialized 的答案。 - helb

2
根据MSDN文档中对于OnDeserialized属性的说明:

当应用于方法时,指定该方法在对象图中的对象反序列化后立即调用。相对于图中其他对象的反序列化顺序是不确定的。

根据我的理解,OnDeserialize方法是在对象反序列化之后被调用的,但并不一定在所有关联对象都被反序列化之后
您在OnDeserialized方法中执行了一个操作,这个操作使用到了聚合的animations_字典,其中包含了必须被反序列化的AnimationManager对象。如果OnDeserializedAnimationManager对象被反序列化之前就被调用了,那么就可以解释您所描述的症状了。
最好自己调用这个方法并移除OnDeserialized属性。

1
有没有一种指定反序列化“顺序”的方法?这样我就可以根据每个对象的依赖关系选择顺序。 - Francesco Bonizzi
@misiMe 如果你足够钻研,可能会找到一种方法,但如果文档说顺序是不确定的,那么如果你想让你的代码可靠地工作,你可能没有太多选择。 - helb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接