2024年5月28日 星期二

使用C#12 Primary Constructor 文/恆逸資深講師高光弘

什麼是Primary Constructor

Primary Constructor是C#的簡化建構函式宣告的語法,最早是用於Record 型別,宣告Record型別的時候,同時定義建構函式及屬性。
未使用Primary Constructor的寫法:

record Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Customer(int id, string name)
    {
        Id = id;
        Name = name;
    }
}             

使用Primary Constructor的寫法:

record Customer(int Id, string Name);          

兩者之間,可以發現Primary Constructor的確能簡化不少程式碼,Id和Name並不是參數,而是屬性。Record型別大多用於DTO(Data Transfer Object)在定義建構函式的時候,能一起定義屬性,的確很適合。

C#12 Primary Constructor

在類別的部分C# 12也提供Primary Constructor。與 Record 語法相同的地方為宣告型別的時候,可以同時定義建構函式:

class Customer(int id, string name);         

不同的地方在於建構函式中的 id 和 name 不是屬性,而是參數。這些參數的範圍是涵蓋整個類別,類別內的方法和屬性是可以自由存取這些參數,而外部程式是無法存取這些參數,外部程式如果要存取參數,需另行宣告屬性:

class Customer(int id, string name) {
    public int Id { get; set; } = id;
    public string Name { get; set; }= name;
}               

在ASP.NET Core中使用Primary Constructor

ASP.NET Core的應用程式,廣泛地使用建構函式搭配Dependency Injection注入所需要的服務,如果搭配Primary Constructor應該可以簡化不少程式碼。

一般未使用Primary Constructor的程式碼:

public class HomeController : Controller
{
    readonly ILogger _logger;

    public HomeController(ILogger logger)
    {
        _logger = logger;
    }
}                      

使用Primary Constructor的程式碼:

在Index方法可以直接透過_logger參數來使用_ILogger服務。這個方式比較簡單,缺點是沒有限制唯讀
進一步將服務設定為唯讀的寫法:

除了要宣告Primary Constructor外,需要額外宣告唯讀欄位(Field),這個方式可以確保服務是唯讀。

由以上的應用程式實作得知,類別的Primary Constructor為什麼不直接宣告屬性的原因。因為搭配DI取得的服務,本來就不需要對外部程式直接開放自由存取,所以僅僅宣告類別層級的參數,但參數本身由於不具備唯讀的特性,如果想要進一步限制成唯讀,開發人員需要另行定義唯讀欄位取得服務。

 

0 意見:

張貼留言