C#基礎(chǔ)知識(shí)之Partial的使用
C# 2.0 可以將類(lèi)、結(jié)構(gòu)或接口的定義拆分到兩個(gè)或多個(gè)源文件中,在類(lèi)聲明前添加partial關(guān)鍵字即可。
例如:下面的PartialTest類(lèi)
class PartialTest { string Str_FieldTest; int Int_FieldTest; public void DoTest() { Debug.Print("Test"); } }
可在不同源文件中寫(xiě)成下面形式:
一個(gè)文件中寫(xiě):
partial class PartialTest { string Str_FieldTest; int Int_FieldTest; }
另一個(gè)文件中寫(xiě):
partial class PartialTest { public void DoTest() { Debug.Print("Test"); } }
一、什么情況下使用分部類(lèi)?
- 處理大型項(xiàng)目時(shí),使一個(gè)類(lèi)分布于多個(gè)獨(dú)立文件中可以讓多位程序員同時(shí)對(duì)該類(lèi)進(jìn)行處理(相當(dāng)于支持并行處理,很實(shí)用);
- 使用自動(dòng)生成的源時(shí),無(wú)需重新創(chuàng)建源文件便可將代碼添加到類(lèi)中。Visual Studio 在創(chuàng)建Windows 窗體、Web 窗體時(shí)都使用此方法。你不用編輯Visual Studio 所創(chuàng)建的文件,便可創(chuàng)建使用這些類(lèi)的代碼。換句話說(shuō):系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)文件(一般記錄的是窗體及窗體中的控件的屬性),另一個(gè)或幾個(gè)文件記錄的是用戶(hù)自己編寫(xiě)的代碼。這兩部分分開(kāi)可以使結(jié)構(gòu)顯得非常清晰,用戶(hù)只需關(guān)注自己負(fù)責(zé)的那部分就行了(需要的話,這兩部分可以互相調(diào)用)。等到了編輯運(yùn)行的時(shí)候,系統(tǒng)會(huì)自動(dòng)將這兩部分合成一個(gè)文件。
二、使用Partial需要注意以下一些情況
- 使用partial 關(guān)鍵字表明可在命名空間內(nèi)定義該類(lèi)、結(jié)構(gòu)或接口的其他部分
- 所有部分都必須使用partial 關(guān)鍵字
- 各個(gè)部分必須具有相同的可訪問(wèn)性,如public、private 等
- 如果將任意部分聲明為抽象的,則整個(gè)類(lèi)型都被視為抽象的
- 如果將任意部分聲明為密封的,則整個(gè)類(lèi)型都被視為密封的
- 如果任意部分聲明繼承基類(lèi)時(shí),則整個(gè)類(lèi)型都將繼承該類(lèi)
- 各個(gè)部分可以指定不同的基接口,最終類(lèi)型將實(shí)現(xiàn)所有分部聲明所列出的全部接口
- 在某一分部定義中聲明的任何類(lèi)、結(jié)構(gòu)或接口成員可供所有其他部分使用
- 嵌套類(lèi)型可以是分部的,即使它們所嵌套于的類(lèi)型本身并不是分部的也如此。如下所示:
class Container { partial class Nested { void Test1(); } partial class Nested { void Test2(); } }
三、使用分布類(lèi)的一些限制
1、要作為同一類(lèi)型的各個(gè)部分的所有分部類(lèi)型定義都必須使用partial 進(jìn)行修飾。如下所示:
public partial class A { } public class A { } // Error, must also be marked partial
2、partial 修飾符只能出現(xiàn)在緊靠關(guān)鍵字class、struct 或interface前面的位置(枚舉或其它類(lèi)型都不能使用partial);
3、要成為同一類(lèi)型的各個(gè)部分的所有分部類(lèi)型定義都必須在同一程序集和同一模塊(.exe 或.dll 文件)中進(jìn)行定義。分部定義不能跨越多個(gè)模塊;
4、類(lèi)名和泛型類(lèi)型參數(shù)在所有的分部類(lèi)型定義中都必須匹配。泛型類(lèi)型可以是分部的。每個(gè)分部聲明都必須以相同的順序使用相同的參數(shù)名。
四、應(yīng)用場(chǎng)景
可以使用partial class的場(chǎng)景很多。這里分析一個(gè)ORM的例子。系統(tǒng)中有一個(gè)Cat類(lèi),屬性ID、Age、Weight都需要存儲(chǔ)到數(shù)據(jù)庫(kù)中,一個(gè)信息系統(tǒng)中常見(jiàn)的需求。通過(guò)讀取數(shù)據(jù)庫(kù)的結(jié)構(gòu),可以用工具生成Cat類(lèi)的代碼。并且ORM框架支持了從數(shù)據(jù)庫(kù)信息生成Cat對(duì)象。
現(xiàn)在的Cat什么動(dòng)作都沒(méi)有,客戶(hù)說(shuō),我們需要一個(gè)Miaow()的函數(shù)。這時(shí)就需要對(duì)ORM生成的Cat類(lèi)進(jìn)行擴(kuò)展了。可以肯定地一點(diǎn)是,我們不能修改自動(dòng)生成的代碼,因?yàn)檫@會(huì)牽涉到數(shù)據(jù)庫(kù)結(jié)構(gòu)與代碼同步的問(wèn)題。解決這個(gè)需求有兩種方法:繼承方式擴(kuò)展,partial class擴(kuò)展。
1、繼承方式擴(kuò)展
工具自動(dòng)生成一個(gè)CatBase類(lèi),這個(gè)類(lèi)只有屬性,嵌入到ORM框架中。既然需要擴(kuò)展功能,很容易想到對(duì)這個(gè)基類(lèi)繼承,于是有了Cat類(lèi)。Cat類(lèi)如愿以?xún)數(shù)赜辛薓iaow()函數(shù)。以前系統(tǒng)中用的是CatBase的實(shí)例,現(xiàn)在創(chuàng)建CatBase實(shí)例的地方需要改為創(chuàng)建Cat的實(shí)例。這個(gè)問(wèn)題讓ORM框架解決吧??蛻?hù)的需求實(shí)現(xiàn)了,我們自己的代碼生成也沒(méi)有遭到破壞,任務(wù)完成。
2、partial class擴(kuò)展
partial class簡(jiǎn)單地說(shuō)就是可以將一個(gè)類(lèi)的代碼寫(xiě)到兩個(gè)或多個(gè)代碼文件中。編譯器在編譯的過(guò)程中將這幾個(gè)文件組合起來(lái)一起編譯。一個(gè)很酷的技術(shù)。工具生成的Cat類(lèi)仍然不變。既然需要增加函數(shù),那么在新建一個(gè)代碼文件,將Miaow()函數(shù)寫(xiě)出來(lái)就可以。需要做的僅僅是將類(lèi)的聲明由class改為partial class,任務(wù)完成。
3、對(duì)比分析
兩種思路都可以實(shí)現(xiàn)需求。孰優(yōu)孰劣需要仔細(xì)分析一下。
- 實(shí)例創(chuàng)建:partial class更加簡(jiǎn)潔。
- 系統(tǒng)復(fù)雜度:對(duì)于系統(tǒng)來(lái)說(shuō),partial class方式下只存在一個(gè)類(lèi),而繼承方式有兩個(gè)類(lèi)。
- 繼承邏輯:從邏輯上講,Cat并不需要一個(gè)基類(lèi)CatBase,這樣做僅僅是因?yàn)樵诖a構(gòu)建過(guò)程中的一個(gè)限制。
- 維護(hù)性:兩種方式下都會(huì)存在兩個(gè)代碼文件,維護(hù)成本并沒(méi)有區(qū)別。
- 可讀性:兩個(gè)Cat文件確實(shí)讓人費(fèi)解。
4、總結(jié)
整體上說(shuō),使用partial class更加優(yōu)雅一些。“繼承”的這種方式比較符合傳統(tǒng)的思維習(xí)慣,而partial class到底是不是滿足開(kāi)閉原則呢,這點(diǎn)確實(shí)不好說(shuō)。不過(guò)在軟件構(gòu)建上,我是一個(gè)實(shí)用主義者,哪種方式好用就用哪一種。在ORM的場(chǎng)景中,partial class更加好一些,但有的時(shí)候,兩個(gè)類(lèi)之間確實(shí)就存在繼承關(guān)系,那么就必須用到繼承了。雖然絕大多數(shù)情況下,都需要繼承方式,但是既然有了partial class技術(shù),我們?cè)谧鲈O(shè)計(jì)時(shí)也需要考慮這個(gè)思路。使用partial class確實(shí)會(huì)帶來(lái)可讀性的損失,尤其是一個(gè)類(lèi)分布在很多個(gè)文件中的時(shí)候,所以文件的命名最好是有一個(gè)規(guī)范來(lái)保證。
到此這篇關(guān)于C#基礎(chǔ)知識(shí)之Partial的使用的文章就介紹到這了,更多相關(guān)C# Partial內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實(shí)現(xiàn)將類(lèi)的內(nèi)容寫(xiě)成JSON格式字符串的方法
這篇文章主要介紹了C#實(shí)現(xiàn)將類(lèi)的內(nèi)容寫(xiě)成JSON格式字符串的方法,涉及C#針對(duì)json格式數(shù)據(jù)轉(zhuǎn)換的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08c# DateTime常用操作實(shí)例(datetime計(jì)算時(shí)間差)
字符串操作DateTime操作,datetime計(jì)算時(shí)間差,取當(dāng)前時(shí)間,更多方法看下面代碼2013-12-12利用WPF實(shí)現(xiàn)Windows屏保的制作
屏保程序的本質(zhì)上就是一個(gè)Win32?窗口應(yīng)用程序。本文將利用WPF實(shí)現(xiàn)Windows屏保的制作,文中的示例代碼簡(jiǎn)潔易懂,對(duì)我們學(xué)習(xí)WPF有一定幫助,感興趣的可以了解一下2022-07-07C#中計(jì)數(shù)排序算法的原理及實(shí)現(xiàn)
計(jì)數(shù)排序是一種線性時(shí)間復(fù)雜度的排序方法,主要通過(guò)統(tǒng)計(jì)元素出現(xiàn)的次數(shù)實(shí)現(xiàn)排序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-10-10C# 延遲Task.Delay()和Thread.Sleep()的具體使用
Thread.Sleep()是同步延遲,Task.Delay()是異步延遲,本文主要介紹了C# 延遲Task.Delay()和Thread.Sleep()的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01