【问题标题】:Serialize objects with inheritance by defining serialize method only in base class?通过仅在基类中定义序列化方法来序列化具有继承的对象?
【发布时间】:2013-12-25 17:07:53
【问题描述】:

我目前正在用 C# 做一个游戏(用于学习目的)。我正在尝试实现加载/保存功能,其中包括将游戏的每个数据保存在一个文件中,并且用户可以重新加载之后保存的游戏。

在游戏中,我为每个玩家附加了一个国家类,每个国家都继承自Nation。目前,我只在基类Nation 上应用了ISerializable 接口,因为子类只有方法覆盖,没有要序列化的新属性。

[Serializable()]
public abstract class Nation : ISerializable 
{
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // save attributes
    }

    public Nation() { } // default constructor, to be able to do "new NationDwarf()" for example.

    // Deserialization constructor.
    public Nation(SerializationInfo info, StreamingContext ctxt)
    {
        // retrieve attributes
    }
}

public class NationDwarf : Nation {
    // some methods override
}
public class NationViking : Nation {
    // some methods override
}

节省似乎很好。但是当我尝试使用这种方法(反序列化)检索数据时,我得到一个异常(第一个玩家有一个 NationDwarf):

序列化异常

缺少反序列化“SmallWorld.NationDwarf”类型对象的构造函数。

所以,我的问题是:我是否需要为 每个 子类指定它是可序列化的并重新定义每个方法(GetObjectData 和构造函数)?有没有办法保持多态性并序列化每个子类,当然能够在反序列化时获得正确的类型?

没找到解决办法,除了在每个子类上重新定义序列化方法,有点重……

谢谢,

【问题讨论】:

    标签: c# serialization binaryformatter


    【解决方案1】:

    短版:是的。如果您实现 ISerializable,那么您的实现应该是虚拟的,并被每个(并且再次:每个)子类覆盖。

    选项:

    • 使用 BinaryFomatter,实现 ISerializable,然后这样做
    • 使用 BinaryFormatter 但不实现 ISerializable
    • 不要使用 BinaryFormatter

    我不介意说我通常提倡最后一种选择。 BinaryFormatter 有...扭结。我个人会使用 protobuf-net,但是:我有偏见(我是作者)

    【讨论】:

    • 我理解您的选择。但在这里,它只是针对一个小型(也是第一个 C#)项目,不想与第三方处理一个小功能:) 所以我将定义每个构造函数,正如@Mike Johnson 解释的那样。无论如何 +1,谢谢。
    【解决方案2】:

    您只需要提供序列化构造函数并在基类中将 GetObjectData 设为虚拟,以便您可以在子类中覆盖它。

    public NationDwarf(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }
    

    虽然 ISerializable 接口是从基类传递的,但运行时仍然需要知道如何专门创建派生类的实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-06
      • 2010-10-14
      相关资源
      最近更新 更多