我正在尝试扩展一个框架。我正在扩展的类之一是序列化的。基类的 GetObjectData()
方法未标记为虚拟,因此我无法覆盖它。
现在,如果对象在作为基类引用时被序列化,则它不是多态的,因此仅调用基类的 GetObjectData
。
有没有办法在不修改基类的 GetObjectData
将其标记为虚拟的情况下解决这个问题?
[编辑] 我扩展了类并添加了一个我想要序列化的属性。下面问题的简单示例
[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);
}
执行保存/加载会产生以下错误:
SerializationException:找不到名为 m_child 的元素。
最佳答案
你需要做两件事:
将
ChildClass
显式标记为ISerializable
。用
new
声明一个GetObjectData
正如 Will 所建议的那样,子类中的修饰符,或
在子类中显式实现接口(interface)。
例如:
[Serializable]
public class ChildClass : ParentClass, ISerializable
{
public int m_child = 73;
public ChildClass()
{ }
public ChildClass(SerializationInfo info, StreamingContext context)
: base(info, context)
{
Debug.WriteLine("Loading child");
m_child = (int)info.GetValue("m_child", typeof(int));
}
public new void GetObjectData(SerializationInfo info, StreamingContext context)
{
Debug.WriteLine("Saving child");
info.AddValue("m_child", m_child, typeof(int));
base.GetObjectData(info, context);
}
}
自 BinaryFormatter.Serialize(Stream, Object)
是非泛型的,将发现和使用最派生的接口(interface)实现。
有关其工作原理的详细信息,请参阅 c# 语言规范 Section 13.4.4 Interface re-implementation :
A class that inherits an interface implementation is permitted to re-implement the interface by including it in the base class list.
关于c# - 扩展其 GetObjectData 方法未标记为虚拟的类时的序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30742511/