![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=1738924491-nEpUsp8bMNm9SjJ4brTcRey2ni2kaqUF-0-1fd8b27e16fab81961c72c1bb7d863b7)
如果左侧的表达式不是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=1738924491-iAhR68dpOxci1wvc0idT4m0rLV0pqISq-0-99d95c62e340e2c43d7f19e91f6e1ddd)
以上代码等价于:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-03.jpg?sign=1738924491-PwpZ52ErxMxscKdGg2mOyRSkQT8cEtY3-0-6bde9e3eea0cdd4a6874fe1559cbc510)
??=运算符可以用于实现延迟计算属性,我们将在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=1738924491-GzXAcXEHreH2lj1hHieWWMGbWog3wRQw-0-8c39d30a967efc0a98420d94f424bce5)
上述代码的最后一行等价于:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-05.jpg?sign=1738924491-CctmXd0LDarHVcpM4rMqDm0EYwHqP8D5-0-bca782816e207dd30fe1dcb9bc26e41d)
null条件运算符同样适用于索引器:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0093-06.jpg?sign=1738924491-GOEvo3xg13qv2pDGKZILMtexrKo3IHeu-0-5a07af63ea449ffe5828adc55b6ce458)
当遇到null时,Elvis运算符将直接略过表达式的其余部分。在接下来的例子中,即使ToString()和ToUpper()方法使用的是标准的.运算符,s的值仍然为null。
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-01.jpg?sign=1738924491-1YkNdk7eIihcVGOHplQimCGmOmCwI2y5-0-8a2e2995888290fbd538cc6fcff24407)
只有直接的左侧运算数可能为null时才有必要重复使用Elvis运算符。因此以下表达式在x和y都为null时依然是健壮的:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-02.jpg?sign=1738924491-hqZoKrIGaykITU23enArzAO3RTxhMbBZ-0-638f2994a4738fef35d99558364cb7a2)
它等价于(唯一的不同在于x.y仅执行了一次):
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-03.jpg?sign=1738924491-S1MSBOTyi5QvykyFnIxAlqrji9N3TP5u-0-e4fd47344f723fe9037904cdf7b7c768)
需要指出,最终的表达式必须能够处理null,因此以下的范例是非法的:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-04.jpg?sign=1738924491-q1OOL6dVGkGhkOmmu7P6coztjpbU0RnM-0-a9ec21725ca2c1e93407ad290222e00e)
我们可以使用可空值类型(请参见4.7节)来修正这个问题。如果你已经对可空值类型有所了解,请参见以下范例代码:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-05.jpg?sign=1738924491-CJme3xUx8tZUeYHFifa8fMkiTsaHS0J8-0-da5849ffc3028ef1b2d8386afe4b2188)
我们也可以使用null条件运算符调用返回值为void的方法:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-06.jpg?sign=1738924491-1c7R0V1Z58DqT2oKgLTlOpk2898Okzmc-0-a4dcd04d2cc3cd7c0b6df75d3db0d859)
如果someObject为null,则表达式将“不执行指令”而不会抛出NullReferenceException异常。
null条件运算符可以和第3章介绍的常用类型成员一起使用,包括方法、字段、属性和索引器。而且它也可以和null合并运算符配合使用:
![](https://epubservercos.yuewen.com/77D764/31147986804769406/epubprivate/OEBPS/Images/0094-07.jpg?sign=1738924491-FSGmkplliaCIJbhsdMFn5Dc0Vm0DX7ml-0-c760573373c17ffe745bcf96967dc15f)