c# - 扩展其 GetObjectData 方法未标记为虚拟的类时的序列化

标签 c# serialization binaryformatter iserializable

我正在尝试扩展一个框架。我正在扩展的类之一是序列化的。基类的 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 的元素。

最佳答案

你需要做两件事:

  1. ChildClass 显式标记为 ISerializable

  2. 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/

相关文章:

C# 将 span 与 SocketAsyncEventArgs 结合使用

c# - 角色.IsUserInRole

python - 在 Python 中序列化 C 结构并通过套接字发送

java - 当我尝试使用 GSON 反序列化 JSON 时,出现空字段

php - 在 jQuery ajax 数据字符串中使用的字符串值的序列化函数

c# - BinaryFormatter 对象图升级

c# - 当玩家触摸边缘时,2D 游戏平台相机会升起

c# - Linq to SQL 插入商标 "™"符号

c# - 设置 BinaryFormatter.TypeFormat 似乎无效

c# - C# 中奇怪的 BinaryFormatter 反序列化错误