public class MyClass {
public string playerName;
}
and I save and load this using a binaryformatter or xml, or json, or whatever, to disk, not playerprefs. Now down the road I need to add something new to MyClass like
public class MyClass {
public string playerName;
public int playerLevel;
}
Now if I try to deserialize any of my old save files the class structure has changed and I won’t be able to interpret them as MyClass anymore.
In my case, I actual don’t care about the file structure at all, I just have a PlayerDataHolder class that I populate and write out to a file. On load I open it and feed the data back all to where it needs to be. So it could be a big string and then I could manually go through each “element” and look for known variables like a JSON structure. But what is a good method for this?
I could also create a NewHolder everytime I change something, inherit from PlayerDataHolder and on failing to deserialize into NewHolder make an attempt at deserializing into PlayerDataHolder, then pull out what I know is present in that version, and fill in the gaps, but that seems like poor practice. Any suggestions?
What do you mean? Why do you think you won’t be able to interpret it as MyClass anymore? If you add a new member variable, and you deserialize a string which doesn’t include that, the new variable will be set to a default value
I’m talking about Json serialisation in this instance at least
A possible way to solve this would be to derive your classes for each version. For example:
public abstract class SaveFileFormat
{
}
public class SaveFileFormatV1 : SaveFileFormat
{
}
public class SaveFileFormatV2: SaveFileFormatV1
{
}
public class SaveFile
{
public List<SaveFileFormat> SaveData;
}
Serialise SaveFile and it should serialise all the data within it because it all derives from SaveFileFormat
When you add extra data fields, create a new SaveFileFormat class. Any existing data files should work.
Edit: Other ways you could do this would be to use reflection and add a property to each version of your class which denotes the type name. When you desialise the file, you can create a Type object from the type name and the deserializer can use that type to deseriallize to. You may need to do this with the above solution as your only type that is guaranteed to fit would be the abstract base class. If you used a type hint within the file, you would know exactly what to use.