解析C#中的分部類和分部方法
可以將類或結(jié)構(gòu)、接口或方法的定義拆分到兩個或多個源文件中。每個源文件包含類型或方法定義的一部分,編譯應(yīng)用程序時將把所有部分組合起來。
分部類
在以下幾種情況下需要拆分類定義:
處理大型項目時,使一個類分布于多個獨立文件中可以讓多位程序員同時對該類進行處理。
使用自動生成的源時,無需重新創(chuàng)建源文件便可將代碼添加到類中。Visual Studio 在創(chuàng)建 Windows 窗體、Web 服務(wù)包裝代碼等時都使用此方法。無需修改 Visual Studio 創(chuàng)建的文件,就可創(chuàng)建使用這些類的代碼。
若要拆分類定義,請使用 partial 關(guān)鍵字修飾符,如下所示:
public partial class Employee { public void DoWork() { } } public partial class Employee { public void GoToLunch() { } }
partial 關(guān)鍵字指示可在命名空間中定義該類、結(jié)構(gòu)或接口的其他部分。所有部分都必須使用 partial 關(guān)鍵字。在編譯時,各個部分都必須可用來形成最終的類型。各個部分必須具有相同的可訪問性,如 public、private 等。
如果將任意部分聲明為抽象的,則整個類型都被視為抽象的。如果將任意部分聲明為密封的,則整個類型都被視為密封的。如果任意部分聲明基類型,則整個類型都將繼承該類。
指定基類的所有部分必須一致,但忽略基類的部分仍繼承該基類型。各個部分可以指定不同的基接口,最終類型將實現(xiàn)所有分部聲明所列出的全部接口。在某一分部定義中聲明的任何類、結(jié)構(gòu)或接口成員可供所有其他部分使用。最終類型是所有部分在編譯時的組合。
注意: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 { }
將從所有分部類型定義中對以下內(nèi)容進行合并:
- XML 注釋
- 接口
- 泛型類型參數(shù)特性
- 類特性
- members
例如,請考慮下列聲明:
partial class Earth : Planet, IRotate { } partial class Earth : IRevolve { }
它們等效于以下聲明:
class Earth : Planet, IRotate, IRevolve { }
限制
處理分部類定義時需遵循下面的幾個規(guī)則:
要作為同一類型的各個部分的所有分部類型定義都必須使用 partial 進行修飾。例如,下面的類聲明將生成錯誤:
public partial class A { } //public class A { } // Error, must also be marked partial
partial 修飾符只能出現(xiàn)在緊靠關(guān)鍵字 class、struct 或 interface 前面的位置。
分部類型定義中允許使用嵌套的分部類型,如下面的示例中所示:
partial class ClassWithNestedClass { partial class NestedClass { } } partial class ClassWithNestedClass { partial class NestedClass { } }
要成為同一類型的各個部分的所有分部類型定義都必須在同一程序集和同一模塊(.exe 或 .dll 文件)中進行定義。分部定義不能跨越多個模塊。
類名和泛型類型參數(shù)在所有的分部類型定義中都必須匹配。泛型類型可以是分部的。每個分部聲明都必須以相同的順序使用相同的參數(shù)名。
下面的用于分部類型定義中的關(guān)鍵字是可選的,但是如果某關(guān)鍵字出現(xiàn)在一個分部類型定義中,則該關(guān)鍵字不能與在同一類型的其他分部定義中指定的關(guān)鍵字沖突:
- public
- private
- protected
- internal
- abstract
- sealed
- 基類
- new 修飾符(嵌套部分)
- 泛型約束
示例 1
下面的示例在一個分部類定義中聲明 CoOrds 類的字段和構(gòu)造函數(shù),在另一個分部類定義中聲明成員 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(); } }
輸出:
CoOrds: 10,15
示例 2
從下面的示例可以看出,您也可以開發(fā)分部結(jié)構(gòu)和接口。
partial interface ITest { void Interface_Test(); } partial interface ITest { void Interface_Test2(); } partial struct S1 { void Struct_Test() { } } partial struct S1 { void Struct_Test2() { } }
分部方法
分部類或結(jié)構(gòu)可以包含分部方法。類的一個部分包含方法的簽名??梢栽谕徊糠只蛄硪粋€部分中定義可選實現(xiàn)。如果未提供該實現(xiàn),則會在編譯時移除方法以及對方法的所有調(diào)用。
分部方法使類的某個部分的實施者能夠定義方法(類似于事件)。類的另一部分的實施者可以決定是否實現(xiàn)該方法。如果未實現(xiàn)該方法,編譯器將移除方法簽名以及對該方法的所有調(diào)用。調(diào)用該方法,包括調(diào)用中的任何計算結(jié)果,在運行時沒有任何影響。因此,分部類中的任何代碼都可以隨意地使用分部方法,即使未提供實現(xiàn)也是如此。如果調(diào)用了未實現(xiàn)的方法,將不會導(dǎo)致編譯時錯誤或運行時錯誤。
在自定義生成的代碼時,分部方法特別有用。這些方法允許保留方法名稱和簽名,因此生成的代碼可以調(diào)用方法,而開發(fā)人員可以決定是否實現(xiàn)方法。與分部類非常類似,分部方法使代碼生成器創(chuàng)建的代碼和開發(fā)人員創(chuàng)建的代碼能夠協(xié)同工作,而不會產(chǎn)生運行時開銷。
分部方法聲明由兩個部分組成:定義和實現(xiàn)。它們可以位于分部類的不同部分中,也可以位于同一部分中。如果不存在實現(xiàn)聲明,則編譯器將優(yōu)化定義聲明和對方法的所有調(diào)用。
// Definition in file1.cs partial void onNameChanged(); // Implementation in file2.cs partial void onNameChanged() { // method body }
- 分部方法聲明必須以上下文關(guān)鍵字 partial 開頭,并且方法必須返回 void。
- 分部方法可以有 ref 參數(shù),但不能有 out 參數(shù)。
- 分部方法為隱式 private 方法,因此不能為 virtual 方法。
- 分部方法不能為 extern 方法,因為主體的存在確定了方法是在定義還是在實現(xiàn)。
- 分部方法可以有 static 和 unsafe 修飾符。
- 分部方法可以為泛型的。約束將放在定義分部方法聲明上,但也可以選擇重復(fù)放在實現(xiàn)聲明上。參數(shù)和類型參數(shù)名稱在實現(xiàn)聲明和定義聲明中不必相同。
可以為已定義并實現(xiàn)的分部方法生成委托,但不能為已經(jīng)定義但未實現(xiàn)的分部方法生成委托。
相關(guān)文章
.net中前臺javascript與后臺c#函數(shù)相互調(diào)用問題
.net中前臺javascript與后臺c#函數(shù)相互調(diào)用問題...2007-12-12C# Distinct和重寫IEqualityComparer時要知道的二三事
這篇文章主要給大家介紹了關(guān)于C# Distinct和重寫IEqualityComparer時要知道的二三事,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06C#自動創(chuàng)建數(shù)據(jù)庫實現(xiàn)代碼
C#下創(chuàng)建數(shù)據(jù)庫的代碼2008-03-03使用C#獲取遠程圖片 Form用戶名與密碼Authorization認證的實現(xiàn)
本篇文章介紹了,使用C#獲取遠程圖片 Form用戶名與密碼Authorization認證的實現(xiàn)。需要的朋友參考下2013-04-04C#基于正則表達式抓取a標(biāo)簽鏈接和innerhtml的方法
這篇文章主要介紹了C#基于正則表達式抓取a標(biāo)簽鏈接和innerhtml的方法,結(jié)合實例形式分析了C#使用正則表達式進行頁面元素的匹配與抓取相關(guān)操作技巧,需要的朋友可以參考下2017-06-06