partial 關鍵字允許將單一類別、結構、介面或方法的定義分散在多個原始檔中,編譯時自動合併。常用於:自動產生程式碼與手寫程式碼分離 (如 WinForms Designer、EF Core Context)、大型類別模組化、多人協作。本文完整說明語法規則、限制與進階特性。
// File1.cs
public partial class Person
{
public string Name { get; set; }
public void SayHello() => Console.WriteLine($"Hi, {Name}");
}
// File2.cs
public partial class Person
{
public int Age { get; set; }
public void SayAge() => Console.WriteLine($"Age: {Age}");
}
// 編譯後等同於
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public void SayHello() { ... }
public void SayAge() { ... }
}
| 目標 | 支援 | 備註 |
|---|---|---|
class | ✅ | |
struct | ✅ | |
interface | ✅ | |
record (C# 9+) | ✅ | |
delegate | ❌ | 不可 partial |
enum | ❌ | 不可 partial |
| 方法 | ✅ (partial method) | 需無回傳值、無 out 參數、預設 private |
partial (C# 2.0+ 要求)。public,其他部分不可標記 internal;若無標記則預設一致。[Serializable]
[Obsolete("v1")]
partial class Entity { }
[DataContract]
[Obsolete("v2")]
partial class Entity { }
// 等同於
[Serializable, Obsolete("v1"), DataContract, Obsolete("v2")]
class Entity { }
// 注意:AllowMultiple=true 的屬性可重複套用 (如 Obsolete),否則會疊加
| 修飾符 | 規則 |
|---|---|
abstract | 任一部分標記 → 整個類別為抽象 |
sealed | 任一部分標記 → 整個類別為密封 |
abstract + sealed | 衝突 → 編譯錯誤 |
static | 靜態類別所有部分必須標記 static |
public partial class Generator
{
// 宣告 (簽名) - 必須無回傳值、無 out、可有 ref/in
partial void OnGenerated(string code);
public void Generate()
{
string code = "// generated";
OnGenerated(code); // 若無實作,呼叫點會被編譯器移除 (零成本)
}
}
// 另一個檔案可選擇實作
public partial class Generator
{
partial void OnGenerated(string code)
{
Console.WriteLine("Generated: " + code);
File.WriteAllText("output.cs", code);
}
}
特性:
Form1.Designer.cs (自動產生) + Form1.cs (手寫)。OnModelCreating 部分方法分離實體設定。Order.Core.cs、Order.Pricing.cs、Order.Shipping.cs 分模組維護。partial class DTO 讓開發者補充驗證邏輯。CS0260:修飾符不一致 (如一部分 public 一部分 internal)。CS0261:基類不一致。CS0759:Partial method 宣告有實作但簽名不符 (如回傳值型別不同)。