为何两段用null传播运算符的C#代码执行差异?一段抛ArgumentNullException
为什么两段C#代码的null处理行为不同?
问题代码对比
抛出ArgumentNullException的代码
string text = null; var x = text?.Split('#'); var y = x.ElementAtOrDefault(1);
无异常的代码
string text = null; var z = text?.Split('#').ElementAtOrDefault(1);
修复后的无异常代码
string text = null; var x = text?.Split('#'); var y = x?.ElementAtOrDefault(1);
原因解析
第一段代码抛出异常的本质
当text为null时:
text?.Split('#')触发null条件运算符的短路逻辑:因为左侧text是null,直接返回null,不会执行Split方法。此时变量x的类型是string[]?(可空字符串数组),值为null。- 调用
x.ElementAtOrDefault(1)时,ElementAtOrDefault是LINQ的扩展方法,它要求传入的source参数(即这里的x)不能为null。当x是null时,方法内部会立即抛出ArgumentNullException。
第二段代码无异常的关键
这里的核心是null条件运算符的链式短路作用:
当text为null时,text?.Split('#')直接返回null,后续的.ElementAtOrDefault(1)并不会被执行——因为?.的短路逻辑会让整个表达式直接返回null,根本不会去调用ElementAtOrDefault方法。只要起始的text是null,整个链式表达式就会短路返回null,不会触发任何后续方法的参数检查。
修复第一段代码的逻辑
在第一段代码中,x可能为null,所以需要对x也使用?.运算符,确保当x为null时,x?.ElementAtOrDefault(1)直接返回null,不会执行ElementAtOrDefault方法,从而避免异常。
内容的提问来源于stack exchange,提问作者Dimitris Maragkos
相关产品推荐
相关产品推荐

