類別提供多個建構函式,參數組合不同,但初始化邏輯大部分重疊。傳統做法抽取 Init(...) 私有方法,但存在缺點:
1. 無法初始化 readonly 欄位 (僅能在建構函式中指派)
2. 無法呼叫基類建構函式 (base(...))
3. 程式碼分散、易遺漏同步更新
public class Person
{
private readonly string _name;
private readonly int _age;
// 主要建構函式 (最完整參數)
public Person(string name, int age)
{
_name = name;
_age = age;
}
// 簡化建構函式 → 委派給主要建構函式
public Person(string name) : this(name, 18) { }
// 無參數建構函式 → 委派給簡化建構函式
public Person() : this("Unknown") { }
}
this(...):呼叫**同類別**其他建構函式,**必須為第一行陳述式**。base(...):呼叫**基類**建構函式,同樣必須為第一行。this(...) 和 base(...) (二擇一)。this/base,隱含呼叫 base() (基類無參數建構函式)。
public class Employee : Person
{
private readonly string _department;
// 完整參數
public Employee(string name, int age, string dept) : base(name, age)
{
_department = dept;
}
// 簡化參數
public Employee(string name, string dept) : this(name, 18, dept) { }
public Employee(string name) : this(name, "General") { }
}
| 特性 | Init 方法 | 建構函式鏈結 (this/base) |
|---|---|---|
| 初始化 readonly 欄位 | ❌ 無法指派 | ✅ 直接指派 |
| 呼叫基類建構函式 | ❌ 無法呼叫 | ✅ base(...) |
| 程式碼集中度 | 分散 | 集中於主要建構函式 |
| 編譯器檢查 | 執行期才發現遺漏 | 編譯期強制參數匹配 |
| 可讀性 | 需跳轉查看 Init | 一眼看清委派關係 |
// ❌ 錯誤:this/base 不在第一行
public Person(string name)
{
Console.WriteLine("Log"); // 先執行其他陳述式
this(name, 18); // 編譯錯誤
}
// ❌ 錯誤:同時使用 this 和 base
public Person(string name) : this(name, 18), base(name) { } // 編譯錯誤
// ✅ 正確:this 在第一行,基類由被呼叫的建構函式處理
public Person(string name) : this(name, 18) { }
// Primary Constructor (類別/結構/Record)
public class Person(string name, int age = 18)
{
public string Name { get; } = name;
public int Age { get; } = age;
// 方法中直接使用參數 name, age
public void Print() => Console.WriteLine($"{Name}, {Age}");
}
// 使用
var p1 = new Person("Alice");
var p2 = new Person("Bob", 25);
主要建構函式參數自動成為可存取的欄位/屬性,**徹底消除樣板碼**,為新專案首選語法。
**建構函式鏈結 (: this/: base) 是 C# 核心語法特性**,解決多建構函式重複初始化、readonly 指派、基類呼叫三大痛點。C# 12+ 專案請直接採用 **Primary Constructor** 進一步簡化。