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

如何让Newtonsoft Json反序列化不可写的数组属性?

解决Json.NET反序列化只读数组属性的问题

针对你遇到的只读数组属性Bar无法被Json.NET正确反序列化的问题,可以通过自定义Json转换器实现逐个元素赋值到已初始化的数组实例中,具体步骤如下:

1. 实现自定义数组转换器

创建一个通用转换器,用于处理只读数组的反序列化逻辑:

public class ReadOnlyArrayConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(T[]);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jsonArray = JArray.Load(reader);
        var existingArray = existingValue as T[];
        
        // 如果没有已存在的数组实例,直接返回新数组
        if (existingArray == null)
            return jsonArray.ToObject<T[]>();

        // 逐个将JSON数组元素赋值到已有数组的对应索引
        for (int i = 0; i < Math.Min(jsonArray.Count, existingArray.Length); i++)
        {
            existingArray[i] = jsonArray[i].ToObject<T>(serializer);
        }
        
        return existingArray;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // 序列化沿用默认逻辑
        serializer.Serialize(writer, value);
    }
}

2. 应用转换器

有两种方式可以让Json.NET使用这个转换器:

方式一:标记在目标属性上

直接给TestClass的Bar属性添加特性:

/// <summary>
/// 无法修改的外部类
/// </summary>
public class TestClass
{
    public string Foo { get; set; }

    [JsonConverter(typeof(ReadOnlyArrayConverter<int>))]
    public int[] Bar { get; } = new int[3];
}

方式二:全局注册转换器

如果多个类需要处理类似场景,可以在序列化配置中全局添加转换器:

var settings = new JsonSerializerSettings();
settings.Converters.Add(new ReadOnlyArrayConverter<int>());

// 序列化
string json = JsonConvert.SerializeObject(testClass, settings);
// 反序列化
TestClass result = JsonConvert.DeserializeObject<TestClass>(json, settings)!;

效果验证

经过上述修改后,反序列化得到的result.Bar[0]会正确赋值为3,和原对象的数组内容一致。转换器会优先复用类中已初始化的数组实例,避免创建新数组,同时自动处理索引越界问题(只赋值到已有数组的长度范围内)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:45:49