類,開始學面向對象的時候,我們就開始學這個。按道理來說,應該沒有什么好的。其實這里面還是有很多可以挖掘的知識點。這篇重點闡述部分類partial。
部分類的關鍵字partial ,它只能聲明在class struct,interface之前。先來個簡單的例子:新建類庫:AssemblyLibrary並建PulClass類文件
public partial class PulClass { public int ID { get; set; } }
這就是一個簡單的部分類。你可以只有一個partial class。但是為了更好的說明這個例子。簡單點,直接在下面加入下面的代碼:
public partial class PulClass { public int Name { get; set; } }
我們用ILSpy來看看生成的代碼是怎么樣的
很簡單吧。
那是不是,我們可以再不同的程序集中使用partial呢。答案是否定的。類--繼承,封裝,多態。試想下如果在不同的程序集中使用部分類,那么類的封裝不就是打破了嗎?
實驗是檢驗真理的唯一標准。還是讓vs直接告訴我們吧,新建項目ConsolTest,引用剛剛的類庫AssemblyLibrary
直接報錯。
那partial的適用范圍是什么呢?msdn的解釋:
要成為同一類型的各個部分的所有分部類型定義都必須在同一程序集和同一模塊(.exe 或 .dll 文件)中進行定義。 分部定義不能跨越多個模塊。
類的訪問性有public,private,protect還有其他亂七八糟的修飾關鍵字,這些會不會影響的partial呢?我也不確定,如果不會,那么一個public和一個private,我想,編譯出來應該是 private,如果有,你懂的,關鍵字一致,實驗下。
public partial class PulClass { public int ID { get; set; } } private partial class PulClass { public int Name { get; set; } }
直接報錯:錯誤 1 命名空間中定義的元素無法顯式聲明為 private、protected 或 protected internal
看來,partial不能和private和protected和protected innernal一起使用。那么類的默認的可訪問性是,private,如果 我們省缺,他默認 的是什么呢?我們去掉,編譯用ILSpy看下:
看來partial的默認訪問是:internal。
partial類不僅僅可以對屬性進行部分化處理,同樣也可以對特性、方法進行部分化處理。
[ObsoleteAttribute] public partial class PulClass { public int ID { get; set; } } [Serializable] public partial class PulClass { public int Name { get; set; } }
編譯出來的是
using System; namespace AssemblyLibrary { [Obsolete] [Serializable] public class PulClass { public int ID { get; set; } public int Name { get; set; } } }
接口也可以像特性一樣合並。這里就不在累贅了
接口:
partial interface ITest { int ID { get; set; } } partial interface ITest { string Name { get; set; } }
編程生成的:
using System; namespace AssemblyLibrary { internal interface ITest { int ID { get; set; } string Name { get; set; } } }
部分類的最后一部分,partial方法:
方法有執行順序,如果使用partial是什么樣子的呢?
public partial class fangfa { //partial void Run() //{ // Console.WriteLine("partial Run"); //} } public partial class fangfa { protected partial void Run(); }
vs又提示我們錯誤了:錯誤 1 分部方法不能具有訪問修飾符或 virtual、abstract、override、new、sealed 或 extern 修飾符
居然protected都有錯誤,那么public更不用說了,不信,你可以去試試
你們猜猜,如果去掉protected會是什么的結果呢?很有意思哦,我們的編譯器對他進行了優化,把Run方法給去掉了
using System; namespace AssemblyLibrary { public class fangfa { } }
部分方法,必須是void 。說實話,現在我看不出來,部分方法有什么好處,部分 類在以前的代碼管理器中,我們可以同時維護一個類。如果用TFS的話,部分類的用處也不大,因為TFS可以合並N個人寫的代碼,不過我不會設置。哈哈
對了,差點忘記了泛型類?不知道這個會是怎么樣的?試試吧
[ObsoleteAttribute] public partial class PulClass<T> { public int ID { get; set; } public T Create() { return default(T); } } [Serializable] public partial class PulClass<T> { public int Name { get; set; } }
static void Main(string[] args) { PulClass<int> pu = new PulClass<int>(); pu.ID = 1; Console.WriteLine(pu.Create().ToString()); Console.Read(); }
細心的朋友,估計看到的vs報的警告,這個是使用了ObsoleteAttribute這個特性的原故。
泛型 方法也是可以部分類的,個人感覺部分方法很雞肋,就不多說了,想知道可以自己試試。