Help with C# inheritance

So I need a little help from the C# guru’s here. Basically I want to write a class that contains all the basic functions to deal with XML files (save, load) , then extend that class into a new class which implements the specific variables to be stored in the XML file.

So I have my generic XMLData class here:

using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using UnityEngine;

[System.Serializable]
[XmlRoot("XMLData")]
public class XMLData {
		
	public void Save(string path)
	{
		var serializer = new XmlSerializer(typeof(XMLData));
		using(var stream = new FileStream(path, FileMode.Create))
		{
			serializer.Serialize(stream, this);
		}
	}
	
	public XMLData Load(string path)
	{
		var serializer = new XmlSerializer(typeof(PanoData));
		using(var stream = new FileStream(path, FileMode.Open))
		{
			return serializer.Deserialize(stream) as XMLData;
		}
	}
	
	public XMLData Load(StringReader xml)
	{
		var serializer = new XmlSerializer(typeof(PanoData));
		return serializer.Deserialize(xml) as XMLData;
	}
}

and then I am extending that class like this

using UnityEngine;
using System.Collections;

public class UpdateData : XMLData {
	public int version;
	
	
}

now ideally what I would want to do is go

UpdateData updateData = new UpdateData();

updateData.version = 10;

updateData.save(“C:\save.xml”);

But the thing is my save and load functions cast everything as an XMLData object, but when I extend the XMLData class into the UpdateData class, in order to save the UpdateData information through those inherited save and load functions, they need to be casting everything as UpdateData. But they aren’t so it doesn’t work.

How would I make this work. Is it even possible to make something like this work? Is there a way to tell those inherited functions to cast everything as the data type that is extending them?

My first code experiment to solve your problem would look as follows. Keep in mind that I haven’t tested it or though about all the consequences. And especially I don’t know if it works with the XmlRoot stuff.

using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using UnityEngine;

[System.Serializable]
[XmlRoot("XMLData")]
public abstract class XMLData {

	public abstract void Save (string path);
	public abstract XMLData Load(string path);
	public abstract XMLData Load(StringReader xml);
}
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using UnityEngine;

public class UpdateData : XMLData {
	public int version;

	public override void Save (string path)
	{
		var serializer = new XmlSerializer(typeof(UpdateData));
		using(var stream = new FileStream(path, FileMode.Create))
		{
			serializer.Serialize(stream, this);
		}
	}
	
	public UpdateData LoadUpdateData (string path)
	{
		var serializer = new XmlSerializer(typeof(UpdateData));
		using(var stream = new FileStream(path, FileMode.Open))
		{
			return serializer.Deserialize(stream) as UpdateData;
		}
	}
	
	public UpdateData LoadUpdateData (StringReader xml)
	{
		var serializer = new XmlSerializer(typeof(UpdateData));
		return serializer.Deserialize(xml) as UpdateData;
	}
	
	public override XMLData Load (string path) {
		return (LoadUpdateData (path));
	}
	
	public override XMLData Load (StringReader xml)
	{
		return (LoadUpdateData (xml));
	}
}

Hmm well thats not really alot easier than just copying pasting the functions…

Thank you for help though.

You may use a generic solution in that case. I personally would redesign the code for that and use e.g. a generic class XMLStorage where SerializedData : XMLData.
The following code does not use a generic class, but generic methods, which is not the best solution in my opinion. But it may work.

using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using UnityEngine;

[System.Serializable]
[XmlRoot("XMLData")]
public class XMLData {

	public void Save <SerializedData> (string path) where SerializedData : XMLData
	{
		var serializer = new XmlSerializer(typeof (SerializedData));
		using(var stream = new FileStream(path, FileMode.Create))
		{
			serializer.Serialize(stream, this);
		}
	}
	
	public SerializedData Load <SerializedData> (string path) where SerializedData : XMLData
	{
		var serializer = new XmlSerializer(typeof (SerializedData));
		using(var stream = new FileStream (path, FileMode.Open))
		{
			return serializer.Deserialize (stream) as SerializedData;
		}
	}
	
	public SerializedData Load <SerializedData> (StringReader xml) where SerializedData : XMLData
	{
		var serializer = new XmlSerializer(typeof (SerializedData));
		return serializer.Deserialize(xml) as SerializedData;
	}
}

Your UpdateData saving would look as follows (without the version stuff):
XMLData xmlData = new XMLData();
xmlData.save (“C:\save.xml”);

Load should probably be a static function if you are returning a fresh XMLData object.

Antitheory, you are right. I haven’t though about it a lot. I just made it generic.