![C# 10核心技术指南](https://wfqqreader-1252317822.image.myqcloud.com/cover/89/52513089/b_52513089.jpg)
2.10 null运算符
C#提供了三个简化null处理的运算符:null合并运算符、null合并赋值运算符和null条件运算符。
2.10.1 null合并运算符
null合并运算符写作??。它的意思是“如果左侧操作数不是null,则结果为操作数;否则结果为另一个值。”例如:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-01.jpg?sign=1739583878-R5dJ9Ajp58I67L9P189mu059MCZP94UB-0-4867ddac32266fa9856b785a19340316)
如果左侧的表达式不是null,则右侧的表达式将不会进行计算。null合并运算符同样适用于可空值类型(请参见4.7节)。
2.10.2 null合并赋值运算符
null合并赋值运算符(C# 8引入)写作??==。它的含义是“如果左侧操作数为null,则将右侧的操作数赋值给左侧的操作数。”请考虑以下示例:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-02.jpg?sign=1739583878-damP3TbgocKtu4IMuoxn6PsdUuJd6U7b-0-9ef6b75a5d0d4428b8aef8412fc40e2c)
以上代码等价于:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-03.jpg?sign=1739583878-58OevUVzvdY4awQbkwxyELaGxC4AnwbL-0-ca0698ea5ab277ce0786fa56056e6df3)
??=运算符可以用于实现延迟计算属性,我们将在4.12.5节中介绍。
2.10.3 null条件运算符
?.运算符称为null条件运算符或者Elvis运算符(从Elvis表情符号而来),该运算符可以像标准的.运算符那样访问成员或调用方法。当运算符的左侧为null时,该表达式的运算结果也是null而不会抛出NullReferenceException异常。
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-04.jpg?sign=1739583878-m3yFvnfJg8XlGdwCUcord0mdZ6XOsGGO-0-d4f0c4571f102468b7f2c2277ca60d49)
上述代码的最后一行等价于:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-05.jpg?sign=1739583878-I3E7kzSd99BHX6lKkWOEvM9uLl3rJHgV-0-2604f81c4323ffa19df8238dbe6b9a91)
null条件运算符同样适用于索引器:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-06.jpg?sign=1739583878-D0RsxPlBoWxyGoMFGyViZ41lwISPrAZh-0-0726223ad1b071a42585da1d8e908faf)
当遇到null时,Elvis运算符将直接略过表达式的其余部分。在接下来的例子中,即使ToString()和ToUpper()方法使用的是标准的.运算符,s的值仍然为null。
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-01.jpg?sign=1739583878-CDQTemZU8IsPwS3CyEAEsVryWkkrlXOn-0-30a5b364f7f5adeb8281b738d75217f6)
只有直接的左侧运算数可能为null时才有必要重复使用Elvis运算符。因此以下表达式在x和y都为null时依然是健壮的:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-02.jpg?sign=1739583878-cVKiH4XIb084CaAjDCOf0I6W0nbtbQdR-0-f074e34f1436a0061b4df5e88c2ec487)
它等价于(唯一的不同在于x.y仅执行了一次):
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-03.jpg?sign=1739583878-miJPNmB6DsvKYnYfxuNuV0ex8DXOM8uz-0-252b93a3ffc429e97892ff4c6a899d62)
需要指出,最终的表达式必须能够处理null,因此以下的范例是非法的:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-04.jpg?sign=1739583878-wayOq1IvDqcv5xfZsl7vb3cyGsPy15By-0-09ad280cbaa0dd5b29313fe26bd7df44)
我们可以使用可空值类型(请参见4.7节)来修正这个问题。如果你已经对可空值类型有所了解,请参见以下范例代码:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-05.jpg?sign=1739583878-Phffdj4x9Tz9iaIubgWy3i6XRyNH52eP-0-7a8f9165995efa6bb4fd559b3e08e5d6)
我们也可以使用null条件运算符调用返回值为void的方法:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-06.jpg?sign=1739583878-KNa8qghkfcmBBockExl7xbvkRUptbnYV-0-6f5255db12660824715017fbe3db7467)
如果someObject为null,则表达式将“不执行指令”而不会抛出NullReferenceException异常。
null条件运算符可以和第3章介绍的常用类型成员一起使用,包括方法、字段、属性和索引器。而且它也可以和null合并运算符配合使用:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-07.jpg?sign=1739583878-7iEHcjGrgd6kcXH66bnu9HgUqAOSQsPZ-0-1f63732fe0f53e776bf63ff22d6cbbec)