C#如何在赋值前检查空引用?解决运行时绑定空引用错误
解决"Cannot perform runtime binding on a null reference"空引用错误
你的问题核心在于链式访问时没检查中间对象是否为空——你只针对最后一个属性skill_level做了空判断,但在那之前的dataFirst.payload、payload.last_quick_matches或者last_quick_matches.csgo任何一个对象为null的话,直接链式访问就会触发空引用错误,根本轮不到你检查skill_level。
下面是几种正确的检查方式,按简洁度排序:
1. 最简洁:使用空条件运算符(C# 6.0+)
空条件运算符?.会在左侧对象为null时立即终止链式调用,返回null,不会抛出异常。你可以先安全赋值,再判断结果:
// 安全赋值,中间任何一层为null,vrlvl都会是null var vrlvl = dataFirst?.payload?.last_quick_matches?.csgo?.skill_level; // 再检查结果是否有效 if (vrlvl != null) { // 这里使用vrlvl做后续操作 }
如果需要给默认值,还可以结合空合并运算符??:
// 如果skill_level为null或中间某层为空,就用0作为默认值 var vrlvl = dataFirst?.payload?.last_quick_matches?.csgo?.skill_level ?? 0;
2. 逐层显式检查(兼容旧版C#)
如果你的项目还在使用C# 6.0之前的版本,就必须逐层检查每一个可能为空的对象:
if (dataFirst != null && dataFirst.payload != null && dataFirst.payload.last_quick_matches != null && dataFirst.payload.last_quick_matches.csgo != null && dataFirst.payload.last_quick_matches.csgo.skill_level != null) { var vrlvl = dataFirst.payload.last_quick_matches.csgo.skill_level; // 后续操作 }
这种方式虽然繁琐,但能确保每一层都不为空,完全避免空引用错误。
3. 模式匹配简化检查(C# 8.0+)
用C# 8.0的模式匹配可以让代码更清晰,同时捕获中间对象:
// 先确保csgo对象不为null,再访问它的skill_level if (dataFirst?.payload?.last_quick_matches?.csgo is { } csgoObj && csgoObj.skill_level != null) { var vrlvl = csgoObj.skill_level; // 后续操作 }
这里is { } csgoObj是模式匹配的语法,等价于csgo != null,同时把非空的csgo对象赋值给csgoObj,方便后续使用。
额外提醒
如果这个dataFirst是JSON反序列化得到的对象,建议你把模型类中的skill_level(以及其他可能缺失的属性)定义为可空类型(比如int? skill_level而不是int skill_level),这样当JSON中没有这个字段时,反序列化后属性会是null,而不是默认值0,更便于你做空值判断。
内容的提问来源于stack exchange,提问作者Kingsmeister




