部分類別和方法 (C# 程式設計手冊)
可以將類別、結構、介面或方法的定義分割成兩個或多個原始程序檔。 每一個來源檔案都包含型別或方法定義的一個區段,而當編譯應用程式時,就會將所有區段結合起來。
部分類別
有幾種情況需要分割類別定義︰
- 在個別檔案上宣告類別可讓多個程式設計人員同時處理它。
- 您可以將程式代碼新增至 類別,而不需要重新建立包含自動產生來源的來源檔案。 Visual Studio 建立 Windows Forms、Webb 服務包裝函式程式碼等等時,會使用這種方法。 您可以建立使用這些類別的程式碼,不必修改 Visual Studio 建立的檔案。
- 來源產生器 可以在類別中產生額外的功能。
若要分割類別定義,請使用 partial 關鍵字修飾詞,如下所示︰
public partial class Employee
{
public void DoWork()
{
}
}
public partial class Employee
{
public void GoToLunch()
{
}
}
partial
關鍵字表示可在命名空間中定義類別、結構或介面的其他組件。 所有組件都必須使用 partial
關鍵字。 所有組件都必須可在編譯時間取得,以形成最後的型別。 所有組件必須有相同的存取範圍,例如 public
、private
等等。
如果任何組件宣告為抽象的,則整個型別視為抽象的。 如果任何組件宣告為密封的,則整個型別視為密封的。 如果任何組件宣告基底型別,則整個型別會繼承該類別。
指定基底類別的所有組件必須一致,但省略基底類別的組件仍會繼承基底型別。 組件可以指定不同的基底介面,而最後的型別會實作部分宣告列出的所有介面。 在部分定義中宣告的任何類別、結構或介面成員都可供所有其他組件使用。 最後的型別是所有組件在編譯時期的組合。
注意
partial
修飾詞不提供委派或列舉宣告使用。
下列範例顯示巢狀類型可以是部分類型,即使它們內巢狀的類型不是部分本身也一樣。
class Container
{
partial class Nested
{
void Test() { }
}
partial class Nested
{
void Test2() { }
}
}
在編譯時期會合併部分型別定義的屬性。 例如,請考慮下列宣告:
[SerializableAttribute]
partial class Moon { }
[ObsoleteAttribute]
partial class Moon { }
它們相當於下列宣告:
[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }
以下是合併自所有部分型別定義︰
- XML 註解
- interfaces
- 泛型型別參數屬性
- 類別屬性
- 成員
例如,請考慮下列宣告:
partial class Earth : Planet, IRotate { }
partial class Earth : IRevolve { }
它們相當於下列宣告:
class Earth : Planet, IRotate, IRevolve { }
限制
當您使用部分類別定義時,有數個要遵循的規則:
- 表示同型別組件的所有部分型別定義都必須使用
partial
來修改。 例如,下列類別宣告會產生錯誤︰public partial class A { } //public class A { } // Error, must also be marked partial
partial
修飾詞只能緊接在 關鍵詞class
、struct
或interface
之前出現。- 部分型別定義中允許巢狀部分型別,如下例所示︰
partial class ClassWithNestedClass { partial class NestedClass { } } partial class ClassWithNestedClass { partial class NestedClass { } }
- 表示同型別組件的所有部分型別定義都必須在相同的組件和相同的模組 (.exe 或 .dll 檔案) 中定義。 部分定義無法跨越多個模組。
- 所有部分型別定義中的類別名稱和泛型型別參數必須相符。 泛型型別可以是部分的。 每個部分宣告都必須以相同的順序使用相同的參數名稱。
- 部分類型定義上的下列關鍵詞是選擇性的,但如果存在於某個部分類型定義上,則無法與相同類型另一個部分定義上指定的關鍵詞衝突:
如需詳細資訊,請參閱型別參數的條件約束。
範例
在下例中,類別的欄位和建構函式 Coords
,已在一個部分類別定義中宣告,而成員 PrintCoords
,則是在另一個部分類別定義中宣告。
public partial class Coords
{
private int x;
private int y;
public Coords(int x, int y)
{
this.x = x;
this.y = y;
}
}
public partial class Coords
{
public void PrintCoords()
{
Console.WriteLine("Coords: {0},{1}", x, y);
}
}
class TestCoords
{
static void Main()
{
Coords myCoords = new Coords(10, 15);
myCoords.PrintCoords();
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output: Coords: 10,15
下例範例示範您也可以開發部分結構和介面。
partial interface ITest
{
void Interface_Test();
}
partial interface ITest
{
void Interface_Test2();
}
partial struct S1
{
void Struct_Test() { }
}
partial struct S1
{
void Struct_Test2() { }
}
部分方法
部分類別或結構可以包含部分方法。 類別的一個組件包含方法簽章。 可在相同組件或另一個組件中定義實作。
當簽章遵守下列規則時,部分方法不需要實作:
當沒有任何實作時,方法與方法的所有呼叫都會在編譯階段移除。
不符合上述限制的任何方法 (例如 public virtual partial void
方法) 都必須提供實作。 該實作可能由 來源產生器提供。
Partial 方法可讓類別的一部分實施者宣告方法。 類別的另一個部分實施者可以定義該方法。 此區隔有兩種案例很有用:產生重複使用程式代碼的範本,以及來源產生器。
- 範本程式碼:範本會保留方法名稱和特徵標記,讓產生的程式碼可以呼叫方法。 這些方法會遵循限制,讓開發人員決定是否要實作方法。 如果未實作 方法,則編譯程式會移除方法簽章和方法的所有呼叫。 方法的呼叫,包括評估呼叫中的引數可能發生的任何結果,在執行階段沒有任何作用。 因此,即使未提供實作,部分類別中的任何程序代碼都可以自由使用部分方法。 如果呼叫 方法但未實作,則不會產生編譯時間或運行時間錯誤。
- 來源產生器:來源產生器會提供方法的實作。 人類開發人員可以新增方法宣告 (通常會使用來源產生器讀取的屬性)。 開發人員可以撰寫呼叫這些方法的程式碼。 來源產生器會在編譯期間執行,並提供實作。 在此案例中,通常不會遵循可能未實作的部分方法限制。
// Definition in file1.cs
partial void OnNameChanged();
// Implementation in file2.cs
partial void OnNameChanged()
{
// method body
}
- Partial 方法宣告必須以內容關鍵字 partial 作為開頭。
- 部分類型其兩個部分中的 partial 方法特徵標記必須相符。
- 部分方法可以有 static 和 unsafe 修飾詞。
- 部分方法可以為泛型。 定義和實作方法宣告的條件約束必須相同。 參數和類型參數名稱在實作宣告中不必和定義宣告相同。
- 您可以對 已定義和實作的部分方法進行委派,但不能委派 給沒有實作的部分方法。
C# 語言規格
如需詳細資訊,請參閱 C# 語言規格中的部分類型和部分方法。 語言規格是 C# 語法及用法的限定來源。 部分方法的其他功能定義於功能規格中。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應