C# 通过仅在基类中定义Serialize方法来使用继承序列化对象?

C# 通过仅在基类中定义Serialize方法来使用继承序列化对象?,c#,serialization,binaryformatter,C#,Serialization,Binaryformatter,我目前正在做一个C#游戏(用于学习)。我正在尝试实现一个加载/保存功能,它包括将游戏的每个数据保存在一个文件中,用户可以在加载后重新加载保存的游戏 在游戏中,每个玩家都有一个国家类,每个国家都继承自nation。目前,我只在基类Nation上应用了ISerializable接口,因为子类只有方法重写,没有要序列化的新属性 [Serializable()] 公共抽象类国家:ISerializable { public void GetObjectData(SerializationInfo信息、S

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

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

[Serializable()]
公共抽象类国家:ISerializable
{
public void GetObjectData(SerializationInfo信息、StreamingContext上下文)
{
//保存属性
}
public Nation(){}//默认构造函数,例如可以执行“new NationDwarf()”。
//反序列化构造函数。
公共国家(SerializationInfo信息、StreamingContext ctxt)
{
//检索属性
}
}
公共类国家:国家{
//有些方法覆盖
}
国家海盗:国家{
//有些方法覆盖
}
节省似乎很好。但是,当我尝试使用此方法(非序列化)检索数据时,我得到一个异常(第一个播放器有一个NationDwarf):

序列化异常

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

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

我没有找到任何解决方案,除了在每个子类上重新定义序列化方法,这有点重


谢谢,

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

选项:

  • 使用BinaryFomatter,实现ISerializable,然后执行此操作
  • 使用BinaryFormatter,但不实现ISerializable
  • 不要使用二进制格式化程序

我不介意说我通常主张最后一种选择。二进制格式化程序已。。。扭结。就我个人而言,我会使用protobuf net,但是:我有偏见(我是作者)

您只需要提供序列化构造函数,并在基类中使GetObjectData虚拟,以便在子类中重写它

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

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

我理解您的选择。但在这里,它只是针对一个小的(也是第一个C#)项目,不想为了一个小特性与第三方打交道:),所以我将定义每个构造函数,正如@Mike Johnson所解释的+无论如何,谢谢。