C# 14 新功能 feild backed properties

field 關鍵字首見於 C# 13,當時是預覽版功能,並未正式釋出;時至今日的 C# 14 成為了正式版本的功能。

以前

C# 3.0 的屬性(property) 有了一個非常重要的演進 – 自動實作屬性。這降低了原本必須先宣告一個欄位再宣告屬性去存取欄位的麻煩。

如果你歷經過 C# 1.0 ~ 2.0 的時代,應該還記得以前要這樣寫:

 public class MyClass
 {
     private string name;

     public string Name
     {
         get { return name; }

         set { name = value; }
     }
 }

有了自動實作屬性之後,大部分的情形會是這樣寫 (於是開啟了屬性和欄位傻傻分不清楚的時代):

 public class MyClass
 {
     public string Name { get; set; }
 }

但傳統的寫法並沒有完全消失,如果你要在 getter 或 setter 中處理一些額外的事項又得回到傳統的寫法,例如:

 public class MyClass
 {
     private int age;

     public int Age
     {
         get { return age; }
         set
         {
             if (value < 0) { value = 0; }
             age = value;
         }
     }
 }

寫 desktop application – 尤其是 WPF 的開發者應該對這檔事感受特別深。

現在

終於,C# 14 正式發布了 field backed properties 功能 – 我喜歡稱這個是「半自動屬性 (semi-auto properties)」,帶來了一個新的語法關鍵字 field。於是乎我們可以這麼改寫:

 public class MyClass
 {      
     public int Age
     {
         get;
         set
         {
             if (value < 0) { value = 0; }
             field = value;
         }
     }
 }

getter 的部分由於不需要動甚麼手腳,可以保持原有自動實作屬性的寫法;而 setter 則可以使用 field 關鍵字替代原有顯式的欄位宣告,讓編譯器自己去處理與生成關於欄位該有的程式碼。

這功能對於需要在屬性動手腳的開發者真是一大福音,可以少打好多字,它帶來的好處不僅僅如此,讓我們繼續看下去。

強固性提升

我的生活裡常常會有機會處裡別人寫的程式碼,曾經看過這類張冠李戴的情況,明明屬性A存取的是欄位a,但程式碼內部卻是欄位b。在 code review 時遇到這樣的程式碼,我的第一個反應就是…

 public class Sample
 {
     private int x;
     private int y;
     public int X
     {
         get { return x; }
         set
         {
             if (value > 0)
             {
                 y = value;
             }
         }
     }
 }
 

使用 filed backed properties 讓編譯器處理可以減少這類無意之失的問題,提升程式碼的強固性。