如何在反序列化DiscountCodeNode时识别DiscountCode的具体子类类型
如何在反序列化DiscountCodeNode时识别DiscountCode的具体类型
一、如果能控制序列化端(应用A)的配置
这是最可靠的方案,让序列化时携带类型标识,反序列化时自动识别具体子类。
1. 使用Newtonsoft.Json(Json.NET)
在应用A的序列化配置中开启类型信息,应用B用相同配置反序列化:
// 应用A序列化代码 var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, // 自动为多态对象添加类型标记 Formatting = Formatting.Indented }; string json = JsonConvert.SerializeObject(discountCodeNode, settings); // 应用B反序列化代码 var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, // 安全提示:若JSON来源不可信,需限制类型加载范围 TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple }; DiscountCodeNode node = JsonConvert.DeserializeObject<DiscountCodeNode>(json, settings); // 直接判断并转换类型 if (node.codeDiscount is DiscountCodeBasic basicCode) { // 处理DiscountCodeBasic逻辑 } else if (node.codeDiscount is DiscountCodeFreeShipping freeShipCode) { // 处理免邮折扣逻辑 } // 其他子类同理
2. 使用System.Text.Json(.NET Core/.NET 5+)
给基类DiscountCode添加特性,指定子类对应的类型标识:
// 给基类添加特性标记子类 [JsonDerivedType(typeof(DiscountCodeApp), typeDiscriminator: "App")] [JsonDerivedType(typeof(DiscountCodeBasic), typeDiscriminator: "Basic")] [JsonDerivedType(typeof(DiscountCodeBxgy), typeDiscriminator: "Bxgy")] [JsonDerivedType(typeof(DiscountCodeFreeShipping), typeDiscriminator: "FreeShipping")] public abstract class DiscountCode { // 基类属性定义 } // 应用A序列化时自动携带类型标识,应用B直接反序列化 string json = JsonSerializer.Serialize(discountCodeNode); DiscountCodeNode node = JsonSerializer.Deserialize<DiscountCodeNode>(json); // 类型判断与使用 if (node.codeDiscount is DiscountCodeBxgy bxgyCode) { // 处理买赠折扣逻辑 }
二、如果无法控制序列化端(只能处理现有JSON)
只能通过子类的独特属性来判断具体类型:
方法1:解析JObject后判断属性(Newtonsoft.Json)
string json = "接口返回的JSON字符串"; JObject nodeObj = JObject.Parse(json); JToken codeDiscountToken = nodeObj["codeDiscount"]; DiscountCode codeDiscount = null; // 根据子类独有属性判断 if (codeDiscountToken["Percentage"] != null) // DiscountCodeBasic独有属性 { codeDiscount = codeDiscountToken.ToObject<DiscountCodeBasic>(); } else if (codeDiscountToken["FreeShippingThreshold"] != null) // 免邮折扣独有属性 { codeDiscount = codeDiscountToken.ToObject<DiscountCodeFreeShipping>(); } // 其他子类同理 DiscountCodeNode node = new DiscountCodeNode { id = nodeObj["id"].ToString(), codeDiscount = codeDiscount };
方法2:反序列化后直接判断类型
如果已经反序列化为DiscountCodeNode,直接用类型匹配:
DiscountCodeNode node = JsonConvert.DeserializeObject<DiscountCodeNode>(json); // 用GetType()判断 if (node.codeDiscount.GetType() == typeof(DiscountCodeApp)) { var appCode = (DiscountCodeApp)node.codeDiscount; // 处理对应逻辑 } // 或者用is模式匹配更简洁 if (node.codeDiscount is DiscountCodeBxgy bxgyCode) { // 直接使用bxgyCode }
内容的提问来源于stack exchange,提问作者Saghar Francis
相关产品推荐
相关产品推荐

