![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=1738923982-y84A9HW4uxy1rSPJfMheFj7p47xlcEVw-0-c1acd862b65fdd4bb4349458fff82e7f)
如果左侧的表达式不是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=1738923982-brPSzK6P5ciGe0G5TdBvpDsR82DSb6im-0-71fc0d1457d0153b72453343c1a6d512)
以上代码等价于:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-03.jpg?sign=1738923982-etY6K7SBil7CqncE1VDJ6puAPKQj5Wdb-0-c581814a5ebc9f13720ac987e789482e)
??=运算符可以用于实现延迟计算属性,我们将在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=1738923982-IxHBVkp6sN6FluwafhSc3NBTVnyWZpMH-0-e9ded9b2de95083f2b04959bab645289)
上述代码的最后一行等价于:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-05.jpg?sign=1738923982-cyVGMCvxOtkitk0bFKGCDHYdRR2pLRHE-0-3634f641ace90b2e6d8b8831661d4151)
null条件运算符同样适用于索引器:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-06.jpg?sign=1738923982-mFFkkOg6veyTGiODbQNL73D7jUs770Rg-0-085e444b83ea8c569ecfd175de0b2e2c)
当遇到null时,Elvis运算符将直接略过表达式的其余部分。在接下来的例子中,即使ToString()和ToUpper()方法使用的是标准的.运算符,s的值仍然为null。
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-01.jpg?sign=1738923982-xcO5Zu035yU9OnZC0EzWqkfyvySFimE7-0-ae220eb2ec913a979c6e11395f71d1e2)
只有直接的左侧运算数可能为null时才有必要重复使用Elvis运算符。因此以下表达式在x和y都为null时依然是健壮的:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-02.jpg?sign=1738923982-cHXp28aHXKMyZf5cFe2Vu9DDdofWJ6Kq-0-1ea661490192ccec2551350dde373bc7)
它等价于(唯一的不同在于x.y仅执行了一次):
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-03.jpg?sign=1738923982-al7mt86LpJBHzVnrR9rtTiXRNJf4FSQv-0-03f17fafd76e28d5b15668c92581ac8b)
需要指出,最终的表达式必须能够处理null,因此以下的范例是非法的:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-04.jpg?sign=1738923982-Fqcv7U34nV09Dj3ZaG0p6STCJ2gTKmBQ-0-cc628f4e14bc9e96022cb07de7336dd0)
我们可以使用可空值类型(请参见4.7节)来修正这个问题。如果你已经对可空值类型有所了解,请参见以下范例代码:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-05.jpg?sign=1738923982-KybzskFOsYZfEfMJnWFNzkGO66tZIMS4-0-7789548080981d72587cd5d43ade60ca)
我们也可以使用null条件运算符调用返回值为void的方法:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-06.jpg?sign=1738923982-e6csvJOc6f7p1QPqYEQACCGXGHApIFlx-0-ef226c2cec4f8e30d6b7d6da3ac1bbad)
如果someObject为null,则表达式将“不执行指令”而不会抛出NullReferenceException异常。
null条件运算符可以和第3章介绍的常用类型成员一起使用,包括方法、字段、属性和索引器。而且它也可以和null合并运算符配合使用:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-07.jpg?sign=1738923982-ekcZJWgtencmWi8My7os8GwKiznM26Sy-0-094cf507adf34525cf5ecd1096ef65e1)