分部方法以 partial 關鍵字標記,僅能出現在 partial class 或 partial struct 中,且分為「宣告」與「實作」兩部分:
partial class Customer {
// 宣告(類似抽象方法,無主體)
partial void OnNameChanging(string newName);
// 實作(可選,若無則編譯器移除所有呼叫)
partial void OnNameChanging(string newName) {
Console.WriteLine($"名稱即將變更為:{newName}");
}
}
若僅有宣告無實作,編譯器不會發射方法本體,連同呼叫點與引數評估一併移除。例如:
partial class Demo {
partial void Log(int x);
void Test() {
int i = 0;
Log(i++); // 若 Log 無實作,i++ 根本不會執行,i 保持 0
}
}
這對效能敏感或有副作用的引數極為重要。
private(隱含),不可加存取修飾詞voidref、params、this(擴充方法),不可用 outvirtual、abstract、override、externstatic、unsafe、泛型方法自動產生的實體類別在屬性設定前後插入鉤子:
partial class Customer {
string _name;
public string Name {
get => _name;
set {
OnNameChanging(value);
_name = value;
OnNameChanged();
}
}
partial void OnNameChanging(string newName);
partial void OnNameChanged();
}
使用者可在另一個分部檔案實作驗證、通知等邏輯,若不實作則零開銷。
DataContext 衍生類別為每個實體產生 InsertXxx、UpdateXxx、DeleteXxx 分部方法,開發者可覆寫實作軟刪除、審計等行為。
partial class MyClass {
partial void DebugLog(string msg);
void DoWork() {
DebugLog("進入 DoWork"); // 釋出建置自動消失
}
}
#if DEBUG
partial class MyClass {
partial void DebugLog(string msg) => System.Diagnostics.Debug.WriteLine(msg);
}
#endif
缺點:因必須為 private,每個類別都需重複定義。
分部方法是「編譯時期條件編譯」的型別安全替代方案,專為程式碼產生器設計。一般業務邏輯請優先考慮事件、介面或委派模式。