如何基于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
相关产品推荐
相关产品推荐

