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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:35:37