I have a base class defined as follows:
public abstract class XMLBackedObject<T> where T: XMLBackedObject<T>
{
/// <summary>
/// Load the specified xml file and deserialize it.
/// </summary>
/// <param name='filePath'>
/// File path to load
/// </param>
public static T Load(string filePath)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using(FileStream stream = new FileStream(filePath, FileMode.Open))
{
return serializer.Deserialize(stream) as T;
}
}
/// <summary>
/// Save this instance to the specified file path
/// </summary>
/// <param name='filePath'>
/// File path to save to.
/// </param>
public void Save(string filePath)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using(FileStream stream = new FileStream(filePath, FileMode.Create))
{
serializer.Serialize(stream, this);
}
}
}
And classes inherit it as follows:
Config.cs:
using UnityEngine;
using System.Collections.Generic;
[System.Serializable]
public class Config : XMLBackedObject<Config>
{
public Config()
{
}
public string WordDirectoryPath;
public string CommandDirectoryPath;
}
Command.cs:
using UnityEngine;
using System.Collections.Generic;
[System.Serializable]
public abstract class Command : XMLBackedObject<Command>
{
//The word that triggers this command
public Word Word;
//The command's target
public List<Word> Targets;
//Minimum number of targets for the command to be valid
public int RequiredTargets;
//Message to send when bad targets are supplied
public string BadTargetString;
//Message to send when no target is supplied
public string noTargetString;
public Command(Word word, List<Word> targets,int requiredTargets)
{
Targets = targets;
this.Word = word;
this.RequiredTargets = requiredTargets;
}
public Command()
{
Targets = new List<Word>();
}
/// <summary>
/// Execute the command on the supplied targets
/// </summary>
/// <param name='targets'>
/// Targets to process
/// </param>
public abstract void Execute(IEnumerable<Word> targets);
}
MenuNavigationCommand.cs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class MenuChoiceCommand : Command {
public MenuChoiceCommand()
{
}
public MenuChoiceCommand(Word word, List<Word> targets, int requiredTargets) : base(word,targets,requiredTargets)
{
}
public override void Execute (System.Collections.Generic.IEnumerable<Word> targets)
{
}
}
And this is the code that calls the Save functions:
public void BuildTestXMLFiles()
{
Config config = new Config();
config.CommandDirectoryPath = "commdirpath";
config.WordDirectoryPath = "wordirparth";
config.Save (Application.dataPath + "/testconfig.xml");
MenuChoiceCommand command = new MenuChoiceCommand(word,new List<Word>(),2);
command.Targets.Add (word);
command.Save (Application.dataPath + "/testcommand.xml");
}
Config's Save function executes without any hitches, but using Save on MenuNavigationCommand gives me this error:
InvalidOperationException: The type of the argument object 'MenuChoiceCommand' is not primitive.
All I need MenuNavigationCommand to do is save the fields that exist in the Command class it inherits from, not any new fields in MenuNavigationCommand. Is there any way to do this? Or should I just implement a Load and Save method on every class that uses more than one level of inheritance?
EDIT: Added the full source for the files.