You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传入基类参数时反序列化派生类型:自定义Message类序列化异常

解决BinaryFormatter序列化/反序列化派生类丢失数据的问题

你遇到的问题很典型——当用BinaryFormatter处理继承自Message的TestMessage时,反序列化只能得到基类实例,派生类的OtherString属性直接丢失了。这是因为默认情况下,要么序列化时没有正确写入派生类的类型信息,要么反序列化时程序无法识别派生类的类型。下面给你一步步的解决方案:

1. 确保基类和派生类都标记[Serializable]

BinaryFormatter要求所有要序列化的类必须标记[Serializable]特性,基类和派生类都不能少。先修正你的类定义:

[Serializable]
public class Message 
{ 
    public string Name { get; set; } 
}

[Serializable]
public class TestMessage : Message 
{ 
    public string OtherString { get; set; } 
}

2. 检查序列化/反序列化方法的实现

你的SerializeMessage方法如果是类似下面这样的,其实已经能正确写入TestMessage的类型信息了:

public byte[] SerializeMessage(Message message) 
{ 
    using (MemoryStream fs = new MemoryStream()) 
    { 
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(fs, message);
        return fs.ToArray();
    } 
}

问题通常出在反序列化环节。如果你的反序列化方法是这样的,就能自动返回派生类实例:

public Message DeserializeMessage(byte[] data)
{
    using (MemoryStream fs = new MemoryStream(data))
    {
        BinaryFormatter formatter = new BinaryFormatter();
        // 这里会根据序列化时写入的类型信息,自动实例化对应的派生类
        return (Message)formatter.Deserialize(fs);
    }
}

调用的时候,只需要把反序列化的结果强转为TestMessage即可:

// 序列化TestMessage实例
var testMsg = new TestMessage { Name = "Demo", OtherString = "Extra Data" };
byte[] serializedData = SerializeMessage(testMsg);

// 反序列化并强转
var deserializedMsg = (TestMessage)DeserializeMessage(serializedData);
// 此时deserializedMsg.OtherString应该能正确获取到"Extra Data"

3. 处理跨程序集的派生类情况

如果TestMessage和Message不在同一个程序集里,反序列化时可能找不到类型。这时候需要自定义SerializationBinder来指定类型映射:

public class CustomSerializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        // 根据实际的命名空间和类型名调整
        if (typeName.Equals("YourNamespace.TestMessage"))
        {
            return typeof(TestMessage);
        }
        // 基类的类型映射
        return typeof(Message);
    }
}

然后在反序列化时绑定这个自定义Binder:

public Message DeserializeMessage(byte[] data)
{
    using (MemoryStream fs = new MemoryStream(data))
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Binder = new CustomSerializationBinder();
        return (Message)formatter.Deserialize(fs);
    }
}

重要提醒

微软已经将BinaryFormatter标记为过时(Obsolete),因为它存在严重的安全漏洞(攻击者可以构造恶意数据触发代码执行)。如果你的项目是新开发的,建议使用更安全的序列化方案:

  • System.Text.Json:微软官方推荐的轻量、安全JSON序列化库
  • Newtonsoft.Json:功能丰富的老牌JSON序列化库
  • Protobuf-net:基于Protocol Buffers的高效二进制序列化库

内容的提问来源于stack exchange,提问作者user3953989

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:48:03