C# 6:自動屬性的初始設定式

撰寫本文時,Visual Studio 2015 仍為 Preview 版本,但 C# 語言的部分應該已經蠻穩定了,將來不會有太大變動。目前發現原本微軟打算加入的新語法 primary constructor 和 declaration expressions 已被拿掉

在 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 版)

Post Comments

技術提供:Blogger.