I'm trying to extend a framework. One of the classes I am extending is serialized. The base class' GetObjectData()
method is not marked virtual so I can't override it.
Now if object gets serialized when it's referenced as a base class it's not polymorphic so only the base class' GetObjectData
is called.
Is there any way around this without modifying the base class' GetObjectData
to mark it as virtual?
[Edit] I extended the class and added an attribute that I want to serialize. Simple example of the problem below
[Serializable]
public class ParentClass : ISerializable
{
public float m_parent = 1.73f;
public ParentClass()
{ }
public ParentClass(SerializationInfo info, StreamingContext context)
{
Debug.Log("Loading parent");
m_parent = (float)info.GetValue("m_parent", typeof(float));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
Debug.Log("Saving parent");
info.AddValue("m_parent", m_parent, typeof(float));
}
}
[Serializable]
public class ChildClass : ParentClass
{
public int m_child = 73;
public ChildClass()
{ }
public ChildClass(SerializationInfo info, StreamingContext context) : base(info, context)
{
Debug.Log("Loading child");
m_child = (int)info.GetValue("m_child", typeof(int));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
Debug.Log("Saving child");
info.AddValue("m_child", m_child, typeof(int));
base.GetObjectData(info, context);
}
}
void Save()
{
Debug.Log("Starting save");
ParentClass aParent = new ChildClass() as ParentClass;
using (Stream stream = File.Open(fileName, FileMode.Create))
{
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, aParent);
}
Debug.Log("Save complete");
}
void Load()
{
Debug.Log("Starting load");
ChildClass aChild;
using (Stream stream = File.Open(fileName, FileMode.Open))
{
BinaryFormatter bFormatter = new BinaryFormatter();
aChild = bFormatter.Deserialize(stream) as ChildClass;
}
Debug.Log("Load complete" + aChild.m_child);
}
Doing a save/load yields the following error:
SerializationException: No element named m_child could be found.
You need to do two things:
Mark
ChildClass
explicitly as beingISerializable
.Declare a
GetObjectData
with thenew
modifier in the child class as Will suggests,or
Implement the interface explicitly in the child class.
For instance:
Since
BinaryFormatter.Serialize(Stream, Object)
is non-generic, the most derived interface implementation will be discovered and used.For details of why this works, see the c# language specification 17.6.7 Interface re-implementation: