![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=1739253579-0HP5ukCaxzZQZsCPy37M9nx7oFtCsWTp-0-abea2e59692674ff995a5fa67b8b50b0)
如果左侧的表达式不是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=1739253579-eN4f6wtsdCtzPs3XGv3qaezb4mIBv1dq-0-13d2ad1a8d801d91dea1913dd6bf534b)
以上代码等价于:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-03.jpg?sign=1739253579-nm9glFcKyUfP6JNH5KFDui3V4dJmDgyP-0-871f9f8f647d6c51bd47c6f08fb8c7cf)
??=运算符可以用于实现延迟计算属性,我们将在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=1739253579-K8yrDs2HlX03zqKGZHLuPwdeEqdi605n-0-c9118028dca792d9b26ed4ef598c6ceb)
上述代码的最后一行等价于:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-05.jpg?sign=1739253579-eYIymYIL9yCKtga83fYyGuDdlb5CFzW5-0-36af5585ba2fc68aafa0e739b2acd981)
null条件运算符同样适用于索引器:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-06.jpg?sign=1739253579-25Sgi0GbObTQQOiMX4TAO8bG4tiIM65p-0-1f1a3ab7de51d12b92167e34e356eded)
当遇到null时,Elvis运算符将直接略过表达式的其余部分。在接下来的例子中,即使ToString()和ToUpper()方法使用的是标准的.运算符,s的值仍然为null。
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-01.jpg?sign=1739253579-zc9AerQjjTKclbL3KNszdS3thw4ym7cm-0-e5a8345bea7b34834105fd869804f055)
只有直接的左侧运算数可能为null时才有必要重复使用Elvis运算符。因此以下表达式在x和y都为null时依然是健壮的:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-02.jpg?sign=1739253579-L98OcjawW4HsRRqZB9K2Kxv7abSOkWKT-0-9b6bb40fcc44ea0dda7b744259895855)
它等价于(唯一的不同在于x.y仅执行了一次):
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-03.jpg?sign=1739253579-c85MwAvTHUx24dunfW7lmx3BNJJYTSiF-0-f90ad610acbe4938c11d7aab843d7cab)
需要指出,最终的表达式必须能够处理null,因此以下的范例是非法的:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-04.jpg?sign=1739253579-wUXAuoR0jz9rb7RkV2LopYHYbOVZQQWz-0-6ca462d8d15fe6736112bdebe84ba956)
我们可以使用可空值类型(请参见4.7节)来修正这个问题。如果你已经对可空值类型有所了解,请参见以下范例代码:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-05.jpg?sign=1739253579-ZRjN9yKNk0746TsVpvOkbUaL4SliqHrV-0-360ba024f754a7c02d0f091f4ce199b2)
我们也可以使用null条件运算符调用返回值为void的方法:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-06.jpg?sign=1739253579-ZvAhHGu4qebhTgE4eXtlFWdCHmyrPa8z-0-815cf3639dbc45defe5bae82c9cf4e47)
如果someObject为null,则表达式将“不执行指令”而不会抛出NullReferenceException异常。
null条件运算符可以和第3章介绍的常用类型成员一起使用,包括方法、字段、属性和索引器。而且它也可以和null合并运算符配合使用:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-07.jpg?sign=1739253579-oflZrN4mwQ3yqaMOslttG59tV93zrTCP-0-89a15fa3987fedcfb186fba7ddbc8a2f)