如何处理System.NullReferenceException?JSON缺键解析问题求助
解决JSON键缺失导致的System.NullReferenceException
问题核心
你遇到的System.NullReferenceException是因为JSON中部分键在值为0时存在、否则被省略,反序列化后对应的嵌套对象(比如data.thing)或属性为null,直接访问data.thing.item时触发空引用异常。下面是几种无需大量异常捕获的可行方案:
方案1:通过Json.NET配置自动填充默认值
修改反序列化配置,让缺失的键自动填充默认值,同时确保实体类的嵌套属性默认初始化,从根源减少null的出现。
首先,在实体类中给需要默认值的属性标记[DefaultValue],并初始化嵌套对象:
public class Thing { [DefaultValue(0)] public double item { get; set; } } public class Data { // 初始化嵌套对象,避免thing为null public Thing thing { get; set; } = new Thing(); }
然后反序列化时使用配置:
var settings = new JsonSerializerSettings { // 忽略JSON中的null值,不覆盖本地默认值 NullValueHandling = NullValueHandling.Ignore, // 自动填充缺失的键为属性的默认值 DefaultValueHandling = DefaultValueHandling.Populate }; using (StreamReader r = new StreamReader(@"path\file.JSON")) { string json = r.ReadToEnd(); var root = JsonConvert.DeserializeObject<Root>(json, settings); }
方案2:封装安全访问工具函数
写一个通用函数统一处理嵌套属性的空值判断,避免重复代码:
// 针对你的场景,安全获取item值 private static double GetSafeItemValue(Data data) { return data?.thing?.item ?? 0; } // 通用版,支持任意嵌套属性和默认值 private static T GetSafeNestedValue<T>(object source, Func<object, T> selector, T defaultValue = default) { try { return selector(source); } catch (NullReferenceException) { return defaultValue; } }
在GET_DATA中使用:
static Dictionary<string, double> GET_DATA(Data data) { Dictionary<string, double> temp_dict = new Dictionary<string, double>(); // 专用函数版 temp_dict["itemx"] = GetSafeItemValue(data); // 通用函数版(示例) // temp_dict["itemx"] = GetSafeNestedValue(data, d => ((Data)d).thing.item, 0); return temp_dict; }
方案3:直接使用空条件运算符简化判断
C# 6及以上支持?.空条件运算符,配合??空合并运算符,一行代码解决空引用问题:
static Dictionary<string, double> GET_DATA(Data data) { Dictionary<string, double> temp_dict = new Dictionary<string, double>(); // 如果data或thing为null,直接返回0 temp_dict["itemx"] = data?.thing?.item ?? 0; return temp_dict; }
选型建议
- 如果JSON结构稳定,优先用方案1,从反序列化阶段就消除null,代码最干净。
- 如果需要处理大量零散的嵌套属性访问,方案3最简洁,无需额外函数。
- 如果有大量重复的空值判断逻辑,方案2可以统一维护逻辑,减少冗余。
内容的提问来源于stack exchange,提问作者JPWilson
相关产品推荐
相关产品推荐

