首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 分部類別與分部方法深度解析:定義、規則、合併邏輯與實戰應用

     編輯:關於C語言

前言

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 兩個方法。

適用場景

  • 大型專案多人協作:不同開發者同時修改同一類別的不同部分,減少合併衝突。
  • 程式碼產生器共存:設計器產生的代碼置於一個 partial 檔,開發者自訂邏輯置於另一個,互不干擾。
  • 邏輯分層:依功能模組將龐大類別拆分為多個檔案管理。

編譯時合併規則

項目合併行為
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() { } }
}

二、限制與規範

  1. 所有部分必須標記 partial:缺一不可,否則編譯錯誤。
  2. partial 必須緊鄰 class/struct/interface 關鍵字。
  3. 同一組件、同一模組:不可跨越多個 .exe/.dll 專案。
  4. 類別名稱與泛型參數必須一致:泛型 partial 類別每個部分需相同參數名稱與順序。
  5. 以下關鍵字若出現在某部分,不可與其他部分衝突: public、private、protected、internal、abstract、sealed、基類別、new(巢狀)、泛型約束。
  6. 若任一部分標記 abstract → 整個類別為抽象;若任一標記 sealed → 整個類別為密封。
  7. partial 不可用於委派或列舉宣告。

三、分部方法

定義與實作分離

// File1.cs - 定義(簽名)
partial void OnNameChanged();

// File2.cs - 實作(可選)
partial void OnNameChanged() {
    // 方法主體
    Console.WriteLine("Name changed!");
}

核心特性

  • 隱含 private:不可為 public、protected、virtual。
  • 必須回傳 void。
  • 可有 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# 支援大型專案工程化、程式碼產生器友善設計的基石。精通分部類別合併規則、分部方法「定義與實作分離、可選實作、零開銷」特性,能讓你在架構設計、原始碼產生整合、團隊協作中遊刃有餘。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved