C#中根据Type属性反序列化不同层级List<double>类型的JSON
根据Type动态处理JSON反序列化中的Coordinates类型
针对你遇到的问题,这里提供几种实用的解决方案,按推荐程度排序:
方法1:自定义JsonConverter(推荐,类型安全)
这种方式能精确控制反序列化逻辑,完全匹配Type和Coordinates的对应关系,同时支持序列化回JSON。
步骤1:定义目标类并绑定转换器
[JsonConverter(typeof(GeoObjectConverter))] public class GeoObject { public string Type { get; set; } public object Coordinates { get; set; } // 便捷方法:快速获取强类型坐标 public List<double> AsPointCoords() => Coordinates as List<double>; public List<List<double>> AsLineCoords() => Coordinates as List<List<double>>; public List<List<List<double>>> AsPolygonCoords() => Coordinates as List<List<List<double>>>; }
步骤2:实现自定义转换器
public class GeoObjectConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(GeoObject); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jObj = JObject.Load(reader); var type = jObj["type"].Value<string>(); object coords = null; switch (type) { case "X": // 对应List<double> coords = jObj["coordinates"].ToObject<List<double>>(); break; case "Y": // 对应List<List<double>> coords = jObj["coordinates"].ToObject<List<List<double>>>(); break; case "Z": // 对应List<List<List<double>>> coords = jObj["coordinates"].ToObject<List<List<List<double>>>>(); break; default: throw new NotSupportedException($"不支持的Type:{type}"); } return new GeoObject { Type = type, Coordinates = coords }; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var geoObj = value as GeoObject; var jObj = new JObject(); jObj.Add("type", geoObj.Type); switch (geoObj.Type) { case "X": jObj.Add("coordinates", JArray.FromObject(geoObj.AsPointCoords())); break; case "Y": jObj.Add("coordinates", JArray.FromObject(geoObj.AsLineCoords())); break; case "Z": jObj.Add("coordinates", JArray.FromObject(geoObj.AsPolygonCoords())); break; default: throw new NotSupportedException($"不支持的Type:{geoObj.Type}"); } jObj.WriteTo(writer); } }
使用示例
// 反序列化 var json = "{\"type\":\"X\",\"coordinates\":[1.5, 2.8]}"; var geoObj = JsonConvert.DeserializeObject<GeoObject>(json); // 强类型读取坐标 if (geoObj.Type == "X") { var pointCoords = geoObj.AsPointCoords(); // 处理点坐标逻辑 } else if (geoObj.Type == "Y") { var lineCoords = geoObj.AsLineCoords(); // 处理线坐标逻辑 }
方法2:使用dynamic类型(快速实现,无类型检查)
适合小场景临时使用,编译时没有类型校验,运行时需自行保证类型正确:
var json = "{\"type\":\"Y\",\"coordinates\":[[1,2],[3,4]]}"; dynamic dynamicObj = JsonConvert.DeserializeObject(json); if (dynamicObj.type == "Y") { var lineCoords = dynamicObj.coordinates.ToObject<List<List<double>>>(); // 处理逻辑 }
方法3:Object类型配合二次序列化(简单但低效)
把Coordinates定义为object,反序列化后根据Type二次转换,性能较差,不推荐用于大量数据场景:
public class GeoObject { [JsonProperty("type")] public string Type { get; set; } [JsonProperty("coordinates")] public object Coordinates { get; set; } } // 使用示例 var geoObj = JsonConvert.DeserializeObject<GeoObject>(json); if (geoObj.Type == "X") { var pointCoords = JsonConvert.DeserializeObject<List<double>>(JsonConvert.SerializeObject(geoObj.Coordinates)); }
内容的提问来源于stack exchange,提问作者OrLevi
相关产品推荐
相关产品推荐

