?? and ??= 運算子 - Null 聯合運算子

如果 Null 聯合運算子 ?? 不是 null,會傳回其左方運算元的值;否則它會評估右方運算元,並傳回其結果。 如果左方運算元評估為非 Null,?? 運算子不會評估其右方運算元。 Null 聯合指派運算子 ??= 只有當左側運算元評估為 null 時,才會將右側運算元的值指派給左側運算元。 如果左方運算元評估為非 Null,??= 運算子不會評估其右方運算元。

List<int>? numbers = null;
int? a = null;

Console.WriteLine((numbers is null)); // expected: true
// if numbers is null, initialize it. Then, add 5 to numbers
(numbers ??= new List<int>()).Add(5);
Console.WriteLine(string.Join(" ", numbers));  // output: 5
Console.WriteLine((numbers is null)); // expected: false        


Console.WriteLine((a is null)); // expected: true
Console.WriteLine((a ?? 3)); // expected: 3 since a is still null 
// if a is null then assign 0 to a and add a to the list
numbers.Add(a ??= 0);
Console.WriteLine((a is null)); // expected: false        
Console.WriteLine(string.Join(" ", numbers));  // output: 5 0
Console.WriteLine(a);  // output: 0	        

??= 運算子的左側運算元必須是變數、屬性索引子項目。

????= 運算子左側運算元的類型不能是不可為 Null 的實值型別。 尤其您可以使用 Null 聯合運算子搭配未受限制的類型參數:

private static void Display<T>(T a, T backup)
{
    Console.WriteLine(a ?? backup);
}

Null 聯合運算子是右關聯運算子。 也就是說表單的運算式

a ?? b ?? c
d ??= e ??= f

評估為

a ?? (b ?? c)
d ??= (e ??= f)

範例

????= 運算子在下列情況很有用:

  • 在使用 Null 聯合運算子 ?.?[] 的運算式中,您可以使用 ?? 運算子在 Null 條件運算的結果為 null 的運算式中,提供用於評估的替代運算式:

    double SumNumbers(List<double[]> setsOfNumbers, int indexOfSetToSum)
    {
        return setsOfNumbers?[indexOfSetToSum]?.Sum() ?? double.NaN;
    }
    
    var sum = SumNumbers(null, 0);
    Console.WriteLine(sum);  // output: NaN
    
  • 當您使用可為 Null 的實值型別,而且需要提供基礎實值型別的值時,請使用 ?? 運算子,在可為 Null 的實值型別為 null 時,指定要提供的值:

    int? a = null;
    int b = a ?? -1;
    Console.WriteLine(b);  // output: -1
    

    如果可為 Null 型別的值為 null 時要使用的值為基礎實值型別的預設值,請使用 Nullable<T>.GetValueOrDefault() 方法。

  • 您可以使用 throw 運算式作為 ?? 運算子的右方運算元,讓引數檢查程式碼更簡潔:

    public string Name
    {
        get => name;
        set => name = value ?? throw new ArgumentNullException(nameof(value), "Name cannot be null");
    }
    

    上述範例中也會示範如何使用運算式主體成員定義屬性。

  • 您可以使用 ??= 運算子來取代表單的程式碼

    if (variable is null)
    {
        variable = expression;
    }
    

    使用下列程式碼:

    variable ??= expression;
    

運算子是否可多載

運算子 ????= 無法多載。

C# 語言規格

如需 ?? 運算子的詳細資訊,請參閱 C# 語言規格Null 聯合運算子一節。

如需有關 ??= 運算子的詳細資訊,請參閱功能提案注意事項 \(英文\)。

另請參閱