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

如何基于Class_A创建继承序列化功能的Class_B类

复用ISerializable序列化逻辑实现Class_B

没问题,咱们可以通过继承+调整基类构造函数访问权限的方式,让Class_B完美复用Class_A的通用序列化/反序列化逻辑,不用重复写代码。下面是具体实现方案:

第一步:调整基类Class_A的实现

你之前遇到的反序列化构造函数加virtual报错的问题,本质是C#不允许反序列化构造函数为虚函数,但我们可以把它改成protected,让子类能继承调用,同时保持通用逻辑不变:

using System.Reflection;
using System.Runtime.Serialization;

[Serializable]
public class Class_A : ISerializable
{
    public int DISP_SEGS { get; set; }

    // 默认构造函数,子类可通过base()调用
    public Class_A() { }

    // 修改为protected,允许子类继承复用
    protected Class_A(SerializationInfo info, StreamingContext ctxt)
    {
        // 用this.GetType()自动获取当前实例的实际类型(子类Class_B)
        foreach (PropertyInfo pi in this.GetType().GetProperties())
        {
            pi.SetValue(this, info.GetValue(pi.Name, pi.PropertyType));
        }
    }

    public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
    {
        // 同样遍历当前实例的所有属性(包括子类新增的)
        foreach (PropertyInfo pi in this.GetType().GetProperties())
        {
            info.AddValue(pi.Name, pi.GetValue(this));
        }
    }
}

第二步:实现Class_B

只需继承Class_A,添加自己的业务属性即可,完全不用写序列化相关代码:

[Serializable]
public class Class_B : Class_A
{
    // 新增Class_B专属属性
    public string ItemName { get; set; }
    public decimal Price { get; set; }

    // 可选:自定义默认构造函数,调用基类构造
    public Class_B() : base() { }
}

第三步:验证序列化/反序列化逻辑

完全按照你需要的方式使用即可,序列化和反序列化都会自动处理Class_B的所有属性(包括继承自Class_A的DISP_SEGS):

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

// 实例化Class_B并赋值
Class_B cb = new Class_B();
cb.DISP_SEGS = 3;
cb.ItemName = "Sample Item";
cb.Price = 19.99m;

// 序列化到内存流
using (MemoryStream stream = new MemoryStream())
{
    BinaryFormatter bformatter = new BinaryFormatter();
    bformatter.Serialize(stream, cb);

    // 重置流位置,准备反序列化
    stream.Seek(0, SeekOrigin.Begin);

    // 反序列化回Class_B对象
    Class_B deserializedCb = (Class_B)bformatter.Deserialize(stream);

    // 验证结果(输出应为3、Sample Item、19.99)
    Console.WriteLine($"DISP_SEGS: {deserializedCb.DISP_SEGS}");
    Console.WriteLine($"ItemName: {deserializedCb.ItemName}");
    Console.WriteLine($"Price: {deserializedCb.Price}");
}

关键注意点

  • 子类必须加上[Serializable]特性,否则BinaryFormatter会抛出序列化异常。
  • 如果后续子类需要自定义序列化逻辑(比如排除某些属性),可以重写GetObjectData,但记得调用base.GetObjectData(info, ctxt)来处理基类属性;反序列化时,子类可以新增自己的protected反序列化构造函数,并调用base(info, ctxt)。
  • 基类中用this.GetType()而非typeof(Class_A)是核心,这样能自动适配子类的属性,保证通用逻辑的复用性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:47:32