?? 运算符

?? 运算符称为 null 合并运算符,用于定义可以为 null 值的类型和引用类型的默认值。如果此运算符的左操作数不为 null,则此运算符将返回左操作数;否则返回右操作数。

a ?? b 形式的空合并表达式要求 a 为可以为 null 的类型或引用类型。如果 a 为非 null,则 a ?? b 的结果为 a;否则,结果为 b。仅当 a 为 null 时,该操作才计算 b。

 

空合并运算符为右结合运算符,表示操作从右向左进行组合。例如,a ?? b ?? c 形式的表达式按 a ?? (b ?? c) 计算。概括地说,E1 ?? E2 ?? ... ?? EN 形式的表达式返回第一个非 null 的操作数,如果所有操作数都为 null,则返回 null。

表达式 a ?? b 的类型取决于两个操作数类型之间有哪些隐式转换可用。按照优先级顺序,a ?? b 的类型为 A0、A 或 B,其中 a 的类型为 A,b 的类型为 B(如果 b 具有类型),A0 是 A 的基础类型(如果 A 为可以为 null 的类型或者 A 是其他允许的类型)。具体而言,a ?? b 的处理过程如下:

·         如果 A 不是可以为 null 的类型或引用类型,则会发生编译时错误。

·         如果 A 是可为 null 的类型并且存在从 b 到 A0 的隐式转换,则结果类型为 A0。在运行时,首先计算 a。如果 a 不为 null,则 a 解包为类型 A0,这即是结果。否则,计算 b 并转换为类型 A0,这即是结果。

·         否则,如果存在从 b 到 A 的隐式转换,则结果类型为 A。在运行时,首先计算 a。如果 a 不为 null,则 a 即是结果。否则,计算 b 并转换为类型 A,这即是结果。

·         否则,如果 b 具有类型 B 并且存在从 A0 到 B 的隐式转换,则结果类型为 B。在运行时,首先计算 a。如果 a 不为 null,则 a 解包为类型 A0(除非 A 和 A0 类型相同)并转换为类型 B,这即是结果。否则,计算 b 并且 b 作为结果。

·         否则,a 和 b 不兼容,并发生编译时错误。

备注

可以为 null 的类型可以包含值,或者可以是未定义的。?? 运算符定义当可以为 null 的类型分配给非可以为 null 的类型时返回的默认值。如果在尝试将可以为 null 值的类型分配给不可以为 null 值的类型时没有使用 ?? 运算符,则会生成编译时错误。如果使用强制转换,且当前还未定义可以为 null 值的类型,则会引发 InvalidOperationException异常。

有关更多信息,请参见可空类型(C# 编程指南)

即使 ?? 运算符的两个参数都是常量,也不能将其结果视为常量。

示例

C# 
class NullCoalesce
{
    static int? GetNullableInt()
    {
        return null;
    }

    static string GetStringValue()
    {
        return null;
    }

    static void Main()
    {
        // ?? operator example.
        int? x = null;

        // y = x, unless x is null, in which case y = -1.
        int y = x ?? -1;

        // Assign i to return value of method, unless
        // return value is null, in which case assign
        // default value of int to i.
        int i = GetNullableInt() ?? default(int);

        string s = GetStringValue();
        // ?? also works with reference types. 
        // Display contents of s, unless s is null, 
        // in which case display "Unspecified".
        Console.WriteLine(s ?? "Unspecified");
    }
}
本在线速查手册由www.w∈3∈x∈u∈e.com提供,请勿盗用!