C#子类调用父类含this的JSON序列化方法是否包含子类属性
核心结论
默认使用System.Text.Json、无额外配置的前提下,你这段代码返回的序列化结果不会包含子类属性,仅会按照父类Parent的类型结构处理,而且你贴的示例代码本身还有两个会影响序列化结果的基础问题。
先修正示例代码的基础问题
你给出的代码存在两个语法/访问级别问题,会直接导致序列化不符合预期:
ToJsonString方法未声明返回值类型,正确写法应为public string ToJsonString()- 类中的
a、b属性未写访问修饰符,C#中类成员默认是private级别,而System.Text.Json默认仅序列化公共属性,不做额外配置的话两个属性都不会出现在序列化结果中。
修正后可运行的基础代码如下:
using System.Text.Json; public class Parent { public int a { get; set; } public string ToJsonString() { return JsonSerializer.Serialize(this); } } public class Child : Parent { public int b { get; set; } } // 调用代码 Child instance = new Child(); string serialized = instance.ToJsonString();
为什么默认拿不到子类属性
调用继承的ToJsonString方法时,虽然this在运行时确实指向Child类型的实例,但JsonSerializer.Serialize(this)这行代码的泛型类型参数是在编译期推断的:
- 方法定义在
Parent类中,this的编译时类型是Parent,因此编译器会把调用解析为JsonSerializer.Serialize<Parent>(this) System.Text.Json默认不开启多态序列化,会严格按照泛型参数指定的Parent类型扫描可序列化属性,不会自动读取运行时实际类型Child的属性。
举个实际运行的例子,给两个属性赋值后序列化:
Child instance = new Child { a = 1, b = 2 }; string serialized = instance.ToJsonString(); // 输出结果:{"a":1},仅包含父类的公共属性a
怎么让序列化结果包含子类属性
有两种常用实现方式:
- 显式指定运行时类型(兼容所有.NET Core/.NET 5+版本)
修改ToJsonString方法,序列化时传入实例的实际运行时类型:
这时候再调用序列化方法,输出结果为public string ToJsonString() { // 传入this.GetType(),强制按实际运行的类型序列化 return JsonSerializer.Serialize(this, this.GetType()); }{"b":2,"a":1},可以拿到子类属性。 - 配置多态序列化(需要.NET 7及以上版本)
给父类标记JsonDerivedType特性,声明子类的派生类型,开启多态序列化支持:
这种写法不需要修改序列化调用代码,遇到[JsonDerivedType(typeof(Child))] public class Parent { public int a { get; set; } public string ToJsonString() { return JsonSerializer.Serialize(this); } }Child实例时也会自动序列化子类属性。
补充说明:如果你用的是第三方序列化库
Newtonsoft.Json(Json.NET),默认行为和System.Text.Json不同,它会默认读取实例的运行时类型,你原始的写法直接就能序列化出子类属性。
内容的提问来源于stack exchange,提问作者Nantangitan
相关产品推荐
相关产品推荐

