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

多态类型鉴别器反序列化时未转换为枚举的问题求解

解决多态序列化中鉴别器字符串未映射到枚举的问题

核心问题原因

JsonPolymorphic特性的类型鉴别器仅用于识别派生类,不会自动将鉴别器字符串转换为枚举值并赋值给Type属性,因此即便反序列化正确识别了对象类型,Type字段仍会使用枚举的默认值。

最优解决方案:派生类构造函数初始化枚举

利用派生类与枚举值的一一对应关系,在每个派生类的构造函数中直接传入对应的枚举值,通过基类构造函数初始化Type属性,无需依赖JSON数据中的额外字段,也不需要冗余字段或应用层转换。

步骤1:定义枚举类型

public enum PenaltyType
{
    FixedPenalty,
    FixedRatePenalty,
    RelativePenalty
}

步骤2:修改基类Penalty

将Type属性设为只读,通过构造函数传入枚举值初始化:

[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
[JsonDerivedType(typeof(FixedPenalty), typeDiscriminator: "fixedPenalty")]
[JsonDerivedType(typeof(FixedRatePenalty), typeDiscriminator: "fixedRatePenalty")]
[JsonDerivedType(typeof(RelativePenalty), typeDiscriminator: "relativePenalty")]
public abstract class Penalty
{
    public PenaltyType Type { get; }
    public string Description { get; set; }

    protected Penalty(PenaltyType type, string description)
    {
        Type = type;
        Description = description;
    }
}

步骤3:实现派生类

每个派生类通过构造函数调用基类构造方法,传入对应的枚举值:

// FixedPenalty示例
public class FixedPenalty : Penalty
{
    public decimal Amount { get; set; }

    [JsonConstructor]
    public FixedPenalty(string description, decimal amount) 
        : base(PenaltyType.FixedPenalty, description)
    {
        Amount = amount;
    }
}

// RelativePenalty示例
public class RelativePenalty : Penalty
{
    public double Rate { get; set; }
    public string Unit { get; set; }

    [JsonConstructor]
    public RelativePenalty(string description, double rate, string unit)
        : base(PenaltyType.RelativePenalty, description)
    {
        Rate = rate;
        Unit = unit;
    }
}

效果说明

当反序列化你提供的JSON时:

{
   "type": "relativePenalty",
   "description": "string",
   "rate": 10.9,
   "unit": "year"
}

系统会正确识别为RelativePenalty类型,其构造函数会调用基类构造方法,将Type属性设置为PenaltyType.RelativePenalty,无需额外处理即可得到正确的枚举值。

这种方案既保持了模型的简洁性,又确保了枚举值与对象类型的一致性,完全避免了冗余字段或应用层转换的麻烦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:23:37