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

Unity中Newtonsoft.Json反序列化类构造函数参数赋值异常

问题原因分析:Newtonsoft.Json反序列化构造函数参数匹配异常

在Unity 2021.3.12f1中使用Newtonsoft.Json反序列化JSON到自定义C#类时,出现BackWallTextureID、LeftWallTextureID、RightWallTextureID被赋值为0,仅FloorTextureID值正确的异常。修改JSON字段名后问题依旧,只有当构造函数参数名与类属性名完全匹配时,赋值才正常,以下是相关代码与JSON:

初始类代码

[System.Serializable]
public class StallData
{
    public StallData(ulong stallID, StallSurfaceTextureData stallSurfaceTextureData)
    {
        StallID = stallID;
        StallSurfaceTextureData = stallSurfaceTextureData;
    }
    
    [field: SerializeField]
    public ulong StallID{ get; private set; }

    [field: SerializeField]
    public StallSurfaceTextureData StallSurfaceTextureData { get; private set; }
}

[System.Serializable]
public class StallSurfaceTextureData
{
    public StallSurfaceTextureData( int floorTextureID, int leftTextureID, int right, int back)
    {
        Debug.LogFormat($" f {floorTextureID} l {leftTextureID} r {right} b {back}");

        BackWallTextureID = back;
        LeftWallTextureID = leftTextureID;
        RightWallTextureID = right;
        FloorTextureID = floorTextureID;
    }
    
    [field: SerializeField]
    public int BackWallTextureID { get; private set; }
    
    [field: SerializeField]
    public int LeftWallTextureID { get; private set; }
    
    [field: SerializeField]
    public int RightWallTextureID { get;private  set; }
    
    [field: SerializeField]
    public int FloorTextureID { get; private set; }
}

对应JSON

{
  "StallID": 889448,
  "StallSurfaceTextureData": 
  {
    "BackWallWallTextureID": 0,
    "LeftWallWallTextureID": 1,
    "RightWallWallTextureID": 2,
    "FloorTextureID": 3
  }
}

修改后正常工作的类代码(构造函数参数名匹配属性名)

[System.Serializable]
public class StallSurfaceTextureData
{
    public StallSurfaceTextureData( int floorTextureID, int leftWallTextureID, int rightWallTextureID, int backWallTextureID)
    {
        Debug.LogFormat($" f {floorTextureID} l {leftWallTextureID} r {rightWallTextureID} b {backWallTextureID}".ToGreen());

        BackWallTextureID = backWallTextureID;
        LeftWallTextureID = leftWallTextureID;
        RightWallTextureID = rightWallTextureID;
        FloorTextureID = floorTextureID;
    }
    
    [field: SerializeField]
    public int BackWallTextureID { get; private set; }
    
    [field: SerializeField]
    public int LeftWallTextureID { get; private set; }
    
    [field: SerializeField]
    public int RightWallTextureID { get;private  set; }
    
    [field: SerializeField]
    public int FloorTextureID { get; private set; }
}

核心原因

  1. Newtonsoft.Json优先使用构造函数创建对象:默认情况下,框架会优先调用类的构造函数实例化对象,而非直接反射设置属性或字段。
  2. 参数名与JSON字段名的匹配逻辑:框架通过忽略大小写的名称匹配,将JSON字段映射到构造函数参数。如果参数名和JSON字段名差异过大(比如初始代码中right对应RightWallWallTextureID、back对应BackWallWallTextureID),框架无法识别对应关系,就会使用参数类型的默认值(int默认0)调用构造函数,最终导致属性赋值为0。
  3. 匹配成功的条件:当构造函数参数名(如leftWallTextureID)与JSON字段名(LeftWallWallTextureID)的核心名称一致时,框架能识别对应关系,正确传入JSON中的值,属性赋值恢复正常。
  4. [field: SerializeField]的影响:你使用的自动属性加[field: SerializeField]会生成编译器自动字段,但在构造函数优先的逻辑下,框架不会直接处理这些字段,完全依赖构造函数参数的匹配结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 17:50:37