C# 2.0 引入 partial 關鍵字,允許將類別、結構、介面或方法的定義拆分至多個原始檔。這不僅便於大型專案多人協作,更是原始碼產生器(如 Windows Forms 設計器、Web Service 代理、Entity Framework 實體類)與手寫代碼共存的關鍵機制。本文系統梳理語法規則、編譯時合併邏輯、限制條件與分部方法運作機制。
// File1.cs
public partial class Employee {
public void DoWork() { }
}
// File2.cs
public partial class Employee {
public void GoToLunch() { }
}
編譯時合併為單一 Employee 類別,擁有 DoWork 與 GoToLunch 兩個方法。
| 項目 | 合併行為 |
|---|---|
| XML 文件註解 | 合併 |
| 介面清單 | 聯集 |
| 泛型型別參數屬性 | 合併 |
| 類別屬性 | 合併 |
| 成員(方法、屬性、欄位等) | 聯集 |
[SerializableAttribute]
partial class Moon { }
[ObsoleteAttribute]
partial class Moon { }
// 等效於
[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }
partial class Earth : Planet, IRotate { }
partial class Earth : IRevolve { }
// 等效於
class Earth : Planet, IRotate, IRevolve { }
外層類別不必是 partial,內層可以是:
class Container {
partial class Nested { void Test() { } }
partial class Nested { void Test2() { } }
}
partial:缺一不可,否則編譯錯誤。partial 必須緊鄰 class/struct/interface 關鍵字。public、private、protected、internal、abstract、sealed、基類別、new(巢狀)、泛型約束。abstract → 整個類別為抽象;若任一標記 sealed → 整個類別為密封。partial 不可用於委派或列舉宣告。// File1.cs - 定義(簽名)
partial void OnNameChanged();
// File2.cs - 實作(可選)
partial void OnNameChanged() {
// 方法主體
Console.WriteLine("Name changed!");
}
public、protected、virtual。ref 參數,不可有 out 參數。static、unsafe、generic。extern。產生器在生成的類別中宣告分部方法(如 OnCreated、OnSaving),開發者可在另一個 partial 檔選擇性實作。若不實作,零成本;若實作,注入自訂邏輯。典型應用:LINQ to SQL / Entity Framework 實體類別的部分鏈接方法。
// CoOrds.Part1.cs
public partial class CoOrds {
private int x, y;
public CoOrds(int x, int y) { this.x = x; this.y = y; }
}
// CoOrds.Part2.cs
public partial class CoOrds {
public void PrintCoOrds() => Console.WriteLine($"CoOrds: {x},{y}");
// 分部方法:擴展點
partial void OnPrinted();
public void PrintAndNotify() {
PrintCoOrds();
OnPrinted(); // 若未實作,此呼叫被移除
}
}
// CoOrds.User.cs - 使用者代碼
public partial class CoOrds {
partial void OnPrinted() => Console.WriteLine(" [Logged]");
}
partial 是 C# 支援大型專案工程化、程式碼產生器友善設計的基石。精通分部類別合併規則、分部方法「定義與實作分離、可選實作、零開銷」特性,能讓你在架構設計、原始碼產生整合、團隊協作中遊刃有餘。