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

