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

为何JsonConvert.DeserializeObject无法设置私有属性,但PopulateObject可以?

Json.Net中PopulateObject可直接设置私有setter属性的原因

现象说明

使用Json.Net时,常规的JsonConvert.DeserializeObject反序列化私有setter属性,必须给属性添加[JsonProperty]特性才能生效;但使用JsonConvert.PopulateObject填充已实例化的对象时,即便私有setter属性没加[JsonProperty],也能成功赋值。

示例代码

定义待处理类

public class Class_A
{
    [JsonProperty] 
    Class_B m_subData = new Class_B("Default data");
}

public class Class_B{
    public string Data {get;private set;}
    public Class_B(string data){
        Data = data;
    }
}

两种反序列化方式的差异

  • 用DeserializeObject时,Class_B的Data属性会保留默认值,必须给Data加[JsonProperty]才能正常赋值。
  • 用PopulateObject时,无需修改Class_B的代码就能成功填充:
public class DataManager{
    public void DeserializeData(string jsonData){
        var classAObj = (Class_A) Activator.CreateInstance(typeof(Class_A));
        var settings = new JsonSerializerSettings
        {
            ObjectCreationHandling = ObjectCreationHandling.Replace
        };
        JsonConvert.PopulateObject(jsonData, classAObj, settings);
    }
}

核心原因

两者的底层处理逻辑完全不同:

  • DeserializeObject是从无到有创建对象,它会严格遵循Json.Net的序列化规则:默认只识别公共成员,私有setter属性不属于默认序列化范围,必须通过[JsonProperty]明确标记为可序列化成员,才会调用setter赋值。
  • PopulateObject是对已存在的对象进行属性填充,它直接通过.NET的反射机制,绕过访问修饰符的限制,直接修改属性对应的私有后备字段(比如自动属性编译后生成的<Data>k__BackingField)。它不需要调用属性的setter方法,也不需要依赖构造函数,自然不需要[JsonProperty]来授权访问。

简单说:PopulateObject不跟setter打交道,直接改底层字段,所以私有setter的限制对它无效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:10:48