Categories
程式開發

C# 的未來:主構造函數


我們上次提到主構造函數是2014年,當時,C# 6和VB 12的候選列表上去掉了主構造函數。去年底,主構造函數重新出現,作為提案#2691,現在成為C# 9的一個候選項。

主構造函數背後的基本思想是減少初始化類所需的樣板代碼量。

class C(string x)
{
    public string X
    {
        get => x;
        set { 
            if (value == null) 
                throw new NullArgumentException(nameof(X)); 
            x = value; 
        }
    }
}

編譯為…

class C
{
    private string _x;
    
    public C(string x)
    {
        _x = x;
    }
    public string X
    {
        get => x;
        set { 
            if (value == null) 
                throw new NullArgumentException(nameof(X)); 
            x = value; 
        }
    }
}

Richard Gibson對它們的用處進行了總結:

從我們30個類的代碼庫中快速抽樣表明,其中的22個(73%)已定義了顯式構造函數,而有21個(>95%)什麼也沒做,只是設置了私有隻讀字段)人們很少閱讀可以自動生成的代碼(通常被跳過,因為它們通常看上去很傻),因此,它們常常是讓人大吃一驚的錯誤來源。

他繼續解釋道,這些錯誤通常是因為不小心把構造函數參數賦給了錯誤的字段。

這個概念跟我們在C#和VB中更簡單的不可變對象報告的記錄提案有很大的重合。 MgSam寫道:

該提案似乎與目前的記錄提案完全不相容。我不同意提案中的說法,提案提到這比記錄更有用。我認為,這可以節省一些樣板記錄,而記錄(以及自動生成GetHashCode、Equals和ToString相關的功能)在很多場景中有可能節約大量模板。

HaloFour也參與了該話題:

按照為C#提出的記錄方式,它們包括對稱構造和解構,以及基於一組特定屬性的識別。假設這些參數也是屬性,那麼主構造函數把這些都放在一個參數列表中,並且該列表給我們提供了一個可以解構這些屬性的順序。

正如他們所提出的,C#記錄更像Scala的case類或F#單例聯合,並且,這兩種語言都根據它們的構造方式定義構造。

原文鏈接:

C# Futures: Primary Constructors