首页 > 编程笔记 > C#笔记 阅读:14

C# null运算符(??、??== 和 ?.)的用法(附带实例)

C# 提供了三个简化 null 处理的运算符:null 合并运算符、null 合并赋值运算符和 null 条件运算符。

null合并运算符

null 合并运算符写作 ??。它的意思是“如果左侧操作数不是 null,则结果为操作数;否则结果为另一个值”。

例如:
string s1 = null;
string s2 = s1 ?? "nothing";  // s2 计算结果为 "nothing"
如果左侧的表达式不是 null,则右侧的表达式将不会进行计算。null 合并运算符同样适用于可空值类型。

null合并赋值运算符

null 合并赋值运算符(C#8 引入)写作 ??==。它的含义是“如果左侧操作数为 null,则将右侧的操作数赋值给左侧的操作数”。

例如:
myVariable ??= someDefault;
以上代码等价于:
if (myVariable == null) myVariable = someDefault;
??= 运算符可以用于实现延迟计算属性。

null条件运算符

?.运算符称为 null 条件运算符或者 Elvis 运算符(从 Elvis 表情符号而来),该运算符可以像标准的 . 运算符那样访问成员或调用方法。

当 ?. 运算符的左侧为 null 时,该表达式的运算结果也是 null 而不会抛出 NullReferenceException 异常。
System.Text.StringBuilder sb = null;
string s = sb?.ToString();  // 没有错误;s 计算结果为 null
上述代码的最后一行等价于:
string s = (sb == null ? null : sb.ToString());

null 条件运算符同样适用于索引器:
string foo = null;
char? c = foo?[1];  // c 是 null

当遇到 null 时,Elvis 运算符将直接略过表达式的其余部分。在接下来的例子中,即使 ToString() 和 ToUpper() 方法使用的是标准的.运算符,s 的值仍然为 null。
System.Text.StringBuilder sb = null;
string s = sb?.ToString().ToUpper();  // s 计算结果为 null,没有错误
只有直接的左侧运算数可能为 null 时才有必要重复使用 Elvis 运算符。因此以下表达式在 x 和 y 都为 null 时依然是健壮的:
x?.y?.z
它等价于(唯一的不同在于 x.y 仅执行了一次):
x = x == null ? null : (x.y == null ? null : x.y.z)

需要指出,最终的表达式必须能够处理 null,因此以下的范例是非法的:
System.Text.StringBuilder sb = null;
int length = sb?.ToString().Length;  // 非法:int 不能为 null
我们可以使用可空值类型来修正这个问题。如果你已经对可空值类型有所了解,请参见以下范例代码:
int? length = sb?.ToString().Length;  // 可以:int? 可以为 null

我们也可以使用 null 条件运算符调用返回值为 void 的方法:
someObject?.SomeVoidMethod();
如果 someObject 为 null,则表达式将“不执行指令”而不会抛出 NullReferenceException 异常。

null 条件运算符可以和常用类型成员一起使用,包括方法、字段、属性和索引器。而且它也可以和 null 合并运算符配合使用:
System.Text.StringBuilder sb = null;
string s = sb?.ToString() ?? "nothing";  // s 计算结果为 "nothing"

相关文章