C#提供了三个简化null处理的运算符:null合并运算符、null合并赋值运算符和null条件运算符。
null合并运算符写作 ?? 。它的意思是“如果左侧操作数不是null,则结果为操作数;否则结果为另一个值。”例如:
如果左侧的表达式不是null,则右侧的表达式将不会进行计算。null合并运算符同样适用于可空值类型(请参见4.7节)。
null合并赋值运算符(C# 8引入)写作 ??== 。它的含义是“如果左侧操作数为null,则将右侧的操作数赋值给左侧的操作数。”请考虑以下示例:
以上代码等价于:
??= 运算符可以用于实现延迟计算属性,我们将在4.12.5节中介绍。
?. 运算符称为null条件运算符或者Elvis运算符(从Elvis表情符号而来),该运算符可以像标准的 . 运算符那样访问成员或调用方法。当运算符的左侧为null时,该表达式的运算结果也是null而不会抛出 NullReferenceException 异常。
上述代码的最后一行等价于:
null条件运算符同样适用于索引器:
当遇到null时,Elvis运算符将直接略过表达式的其余部分。在接下来的例子中,即使 ToString() 和 ToUpper() 方法使用的是标准的 . 运算符, s 的值仍然为null。
只有直接的左侧运算数可能为null时才有必要重复使用Elvis运算符。因此以下表达式在 x 和 y 都为null时依然是健壮的:
它等价于(唯一的不同在于 x.y 仅执行了一次):
需要指出,最终的表达式必须能够处理null,因此以下的范例是非法的:
我们可以使用可空值类型(请参见4.7节)来修正这个问题。如果你已经对可空值类型有所了解,请参见以下范例代码:
我们也可以使用null条件运算符调用返回值为 void 的方法:
如果 someObject 为null,则表达式将“不执行指令”而不会抛出 NullReferenceException 异常。
null条件运算符可以和第3章介绍的常用类型成员一起使用,包括方法、字段、属性和索引器。而且它也可以和null合并运算符配合使用: