C# 6:自動屬性的初始設定式
文章目錄
撰寫本文時,Visual Studio 2015 仍為 Preview 版本,但 C# 語言的部分應該已經蠻穩定了,將來不會有太大變動。目前發現原本微軟打算加入的新語法 primary constructor 和 declaration expressions 已被拿掉。
在 C# 6 之前,唯讀屬性的 get 方法必須有方法本體,所以通常會有一個與之對應的私有欄位(稱為屬性的 backing field)。範例如下:
C# 6 之後,可使用新的「自動屬性初始設定式」(auto-property initializers)來進一步簡化:
明顯的好處是,自動實作屬性有了初始設定式之後,編譯器不會再強迫你一定要替唯讀屬性定義一個對應的私有欄位。此新增語法的主要特色如下:
另一個可賦予唯讀屬性初始值的地方是建構函式。這個部分也稍有變化。
C# 6 之前:
C# 6 之後:
如果你在寫程式時經常覺得替一堆屬性定義對應的私有欄位很麻煩,希望能夠盡量使用自動實作屬性,那麼你應該會蠻喜歡這個新語法。
底下是更多自動實作屬性的寫法,有的是正確語法,有的則為錯誤示範(右方註解會特別註明無法編譯):
此範例程式碼的第 5 行之所以無法通過編譯,理由已在註解中說明。第 6 行雖然也是利用方法呼叫來設定自動屬性的初值,但它是使用靜態方法,所以能夠通過編譯。
摘自《C# 本事》(alpha 版)
在 C# 6 之前,唯讀屬性的 get 方法必須有方法本體,所以通常會有一個與之對應的私有欄位(稱為屬性的 backing field)。範例如下:
class BeforCSharp6
{
private DateTime _startupTime = DateTime.Now;
public DateTime StartupTime
{
get { return _startupTime; }
}
}
C# 6 之後,可使用新的「自動屬性初始設定式」(auto-property initializers)來進一步簡化:
class NewInCSharp6
{
public DateTime StartupTime { get; } = DateTime.Now;
}
明顯的好處是,自動實作屬性有了初始設定式之後,編譯器不會再強迫你一定要替唯讀屬性定義一個對應的私有欄位。此新增語法的主要特色如下:
- 自動實作屬性的 get 方法可以不寫方法本體。
- 自動實作屬性之後可接著用 = 運算子來加上賦值敘述,以設定該屬性的初始值。此新增的賦值語法只能用於自動實作屬性;若用在一般的屬性,編譯時會報錯。
另一個可賦予唯讀屬性初始值的地方是建構函式。這個部分也稍有變化。
C# 6 之前:
class BeforCSharp6
{
private DateTime _startupTime;
public DateTime StartupTime
{
get { return _startupTime; }
}
public BeforCSharp6(DateTime time)
{
_startupTime = time; // 若寫成 this.StartupTime = time; 會無法通過編譯。
}
}
C# 6 之後:
class NewInCSharp6
{
public DateTime StartupTime { get; }
public NewInCSharp6(DateTime time)
{
this.StartupTime = time;
}
}
如果你在寫程式時經常覺得替一堆屬性定義對應的私有欄位很麻煩,希望能夠盡量使用自動實作屬性,那麼你應該會蠻喜歡這個新語法。
底下是更多自動實作屬性的寫法,有的是正確語法,有的則為錯誤示範(右方註解會特別註明無法編譯):
class NewInCSharp6
{
public DateTime StartupTime { get; } = DateTime.Now; // 編譯 OK。
public string FullName { get; set; } = "Michael Tsai"; // 編譯 OK。
public int Age { get; } = this.GetAge(); // 編譯錯誤:初始設定式不可以呼叫非靜態方法!
public Encoding encoding { get; } = Encoding.GetEncoding("BIG5"); // 編譯 OK。
}
此範例程式碼的第 5 行之所以無法通過編譯,理由已在註解中說明。第 6 行雖然也是利用方法呼叫來設定自動屬性的初值,但它是使用靜態方法,所以能夠通過編譯。
摘自《C# 本事》(alpha 版)