C# null运算符(??、??== 和 ?.)的用法(附带实例)
C# 提供了三个简化 null 处理的运算符:null 合并运算符、null 合并赋值运算符和 null 条件运算符。
例如:
例如:
当 ?. 运算符的左侧为 null 时,该表达式的运算结果也是 null 而不会抛出 NullReferenceException 异常。
null 条件运算符同样适用于索引器:
当遇到 null 时,Elvis 运算符将直接略过表达式的其余部分。在接下来的例子中,即使 ToString() 和 ToUpper() 方法使用的是标准的.运算符,s 的值仍然为 null。
需要指出,最终的表达式必须能够处理 null,因此以下的范例是非法的:
我们也可以使用 null 条件运算符调用返回值为 void 的方法:
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"