Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize objects with inheritance by defining serialize method only in base class?

I am currently doing a game in C# (for studies purpose). I'm trying to implement a Load/Save feature, which consist of saving every data of the game in a file, and the user can be able to reload the game saved after.

In the game I have a nation class attached to each players, and every nation inherit from Nation. For the moment, I have only apply the ISerializable interface on the base class, Nation, because subclasses only have method override and no new attributes to serialize.

[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
}

The saving seems fine. But when I'm trying to retrieve data with this method (unserialization), I get an exception (the first player has a NationDwarf):

SerializationException

The constructor is missing for deserialize an object of type 'SmallWorld.NationDwarf'.

So, my question is : do I need to specify for each subclass that it's serializable and redefine each method (GetObjectData and the constructor) ? Is there a way to keep polymorphism and serialize every subclass, and of course be capable to get the correct type at deserialization?

I didn't find any solutions, except redefine the serialization method on each subclass, which is a bit heavy...

Thanks,

like image 933
Maxime Lorant Avatar asked Mar 21 '23 05:03

Maxime Lorant


1 Answers

Short version: yes. If you implement ISerializable then your implementation should be virtual and overridden by every (and again: every) subclass.

Options:

  • use BinaryFomatter, implement ISerializable, and do that
  • use BinaryFormatter but don't implement ISerializable
  • don't use BinaryFormatter

I dont mind saying that I usually advocate the last option. BinaryFormatter has... kinks. Personally I'd use protobuf-net, but: I'm biased (I'm the author)

like image 184
Marc Gravell Avatar answered Apr 06 '23 17:04

Marc Gravell