Custom Inspector Array Elements not saving

So, I’m trying to create a Custom Inspector for an array of custom classes, and I would like to have the ability to change the class of the array element based on a dropdown list.
In my case, I have an array of the base class (Command), and I would like to be able to change the element to either a TestCommand instance or a TestLongCommand instance (both of which inherit from Command).
The problem now is that when I change the elements, THE VALUE IS NEVER SAVED. Even after I set them to dirty, and set them serializable. So even if I create a list which has a 3 TestCommands and 2 TestLongCommands, they all become 5 Commands when I reload the scene/press play.
Could somebody please help me out? I’ve been searchin for like 4 hours and haven’t been able to find the solution to my problem…

CommandList.cs

[System.Serializable]
public class Command {

	public virtual string commandName{
		get { return this.GetType().Name;}
	}
	...
}

[System.Serializable]
public class CommandList : MonoBehaviour {
	public List<Command> commands;
	public int currCommandIndex = 0;
        ...
}

CommandListEditor.cs

[CustomEditor(typeof(CommandList))]
public class CommandListEditor : Editor {

	CommandList script;

	void OnEnable()
	{
		script = (CommandList)target;
	}

	public override void OnInspectorGUI()
	{
		serializedObject.Update();
		EditorGUILayout.PrefixLabel("Commands");
		SerializedProperty commandsProp = serializedObject.FindProperty("commands");

		List<string> allTypeStrings = new List<string>();
		System.Type[] allTypes = Methods.GetSubclasses<Command>();
		foreach(System.Type type in allTypes)
		{
			allTypeStrings.Add(type.Name);
		}

		int i = 0;
		foreach(SerializedProperty childProp in commandsProp)
		{
			EditorGUILayout.LabelField("[" + i.ToString() + "]");
			//Debug.Log(currValue);

			int currIndex = -1;
			if (script.commands *!= null)*
  •  	{*
    
  •  		for (int j = 0; j < allTypeStrings.Count; ++j)*
    
  •  		{*
    

_ if (allTypeStrings[j] == script.commands*.commandName)_
_
currIndex = j;_
_
}_
_ EditorGUILayout.LabelField(script.commands.commandName);
}*_

* int newIndex = EditorGUILayout.Popup(currIndex, allTypeStrings.ToArray());*
* if (newIndex != currIndex)*
* {*
Debug.Log("Changed from " + ((script.commands != null)?script.commands*.commandName:“NULL”) + " to " + allTypeStrings[newIndex] + " in " + serializedObject.targetObject.name);*
System.Activator.CreateInstance(allTypes[newIndex]) as Command);

_ script.commands = System.Activator.CreateInstance(allTypes[newIndex]) as Command;_

* }*

* childProp.serializedObject.ApplyModifiedProperties();*
* commandsProp.serializedObject.ApplyModifiedProperties();*

* ++i;*
* }*

* if (GUI.changed)*
* {*
* EditorUtility.SetDirty(script);*
* EditorUtility.SetDirty(script.gameObject);*
* Undo.RecordObject(script, “Changed command”);*
* EditorSceneManager.MarkSceneDirty(script.gameObject.scene);*

* Debug.Log(“CHANGED!”);*
* }*

* serializedObject.ApplyModifiedProperties();*
* }*

}

facepalm

Changing it to ScriptableObject and segregating it into different files solved it.

The funny thing was that I DID try it a while back but it didn’t work, and I have no idea why.