Null 聯合運算子的演進

  • 922
  • 0

 Null-coalescing operator 的演進史。

Null 聯合運算子

Null 聯合運算子 -- 符號是兩個問號 ?? ,對於某些狀況,它可以有效地簡化程式碼的內容,例如直覺上我們可能這麼寫:

  static void Main(string[] args)
  {
      Display(null);
      Display("this is a book");

      Console.ReadLine();
  }

  static void Display(string x)
  {           

      if (x != null)
      {
          Console.WriteLine(x);
          return;
      }
      Console.WriteLine("傳入 null");
  }

Display 方法有一個 string 型別的參數 x,方法內部判斷 x 不是 null 則顯示 x,如果是 null 則顯示 "傳入 null"。如果我們使用 null-coalescing operator ,Display 方法內程式碼就會看起來更清爽:

 static void Display(string x)
 {
     Console.WriteLine(x ?? "傳入 null");
 }

在 C# 8.0 出現以前, null-coalescing operator 幾乎沒有甚麼改變,其中一個就是對於型別的限制。過去可以使用這個運算子的型別僅限於參考型別和 Nullable<T>,例如:

 static void Display<T>(T x, T y)
 {
     Console.WriteLine(x ?? y);
 }

這樣的程式碼在 C# 7.3 會出現這樣的訊息。

但是在 C# 8.0 上述的寫法是允許的。但是此種用法僅限於泛型的狀況,以下使用方式仍舊是不會通過編譯。

Null 聯合指派運算子

C# 8.0 增強了新的運算子 -- 符號是 ??=, 這個符號進一步簡化了用法。例如以下的狀況:

 public class MyClass
 {
     private List<string> _addresses;

     public List<string> Address
     {         
         get
         {
             if (_addresses == null)
             {
                 _addresses = new List<string>();
             }
             return _addresses;
         }
     }
 }

在以前頂多只能簡化成這樣:

 public class MyClass
 {
     private List<string> _addresses;

     public List<string> Address
     {         
         get
         {
             _addresses = _addresses ?? new List<string>();
             return _addresses;
         }
     }
 }

使用 C# 8.0 的 null 聯合指派運算子就可以簡化成:

 public class MyClass
 {
     private List<string> _addresses;

     public List<string> Address
     {
         get
         {
            return _addresses ??= new List<string>();        
         }
     }
 }

寫起來真的超開心。