等待着元宵節的到來,過完元宵,這個年也算是過完了,也得開始出去掙錢了,過年回家感受每一個人都以爲很牛,只有本身太渣,爲了不年末再出現這樣尷尬的局面,仍是須要努力幹活。爭取當上CEO,贏取白富美,走上人生巔峯。(生活須要幻想,也須要面對現實,努力獲取一個向上的心態,比起擁有財富要更加的可貴。)git
對於如今還在聊QQ和看博客的同志們,我只想借用上圖問一句「大家不上班麼?...哈哈哈...」。好了,不扯淡了,開始咱們今天的主題。github
C#的類型中,咱們知道最多的就是靜態類,對於靜態類的一些特性在這裏就不作介紹了,由於對於一個.NET開發者來講,靜態類的一些特性應該是有必定的掌握,而且在項目中應用的也是很是多。如今須要介紹的是另外一種類型,那就是「分部類型」,對於「分部類型」的瞭解,不少人估計也就是知道而已,接下來就讓咱們一塊兒來學習一個「分部類型」這一C#的語言特色。服務器
學習「分部類型」,咱們仍是先來了解一下什麼叫作「分部類型」。分部類型是指能夠在多個源文件中爲一個類型編寫代碼。對於分部類型的使用場景,使用最多的地方是部分代碼是自動生成,而其餘部分的代碼爲手寫的類型。「分部類型」是由C#2.0時引入的。在繼承鏈上存在一個沒必要要的連接,會引起某些問題或下降封裝型。工具
咱們如今對於分部類型的定義有一個大體的瞭解,以及對分部類型的應用場景也有一個初步的瞭解,接下來咱們來看一下如何建立分部類型和分部類型的使用方法。單元測試
若是須要建立分部類型,咱們只須要在涉及的每一個文件的類型的聲明部分添加一個上下文關鍵字partial。對於分部類型,編譯器在編譯以前就把全部的文件合併在一塊兒了。在一個文件中代碼能夠調用另一個文件中的代碼。有以下代碼:學習
SegmentType1.cs:測試
partial class SegmentType { private void Add() { Update(); } private void Delete() { } }
SegmentType2.csspa
partial class SegmentType { private void Update() { Delete(); } }
以上是對分部類型作了一個簡單的申明和應用,這兩個.CS文件在編譯器編譯以前就已經合併在一塊兒了。對於分部類型不能在一個文件中編寫成員的一半代碼,而把另一半代碼放到另一個文件中,必須保證每一個獨立的成員必須完整地位於它所處的文件中。以下代碼:設計
SegmentType1.cs:代理
partial class SegmentType { private void Add(string fileName) { FileStream fs = null; try { fs = File.Create(fileName); } } }
SegmentType2.cs
partial class SegmentType { private void Update() { Add(); catch (ArgumentException arex) { throw arex; } finally { if (fs != null) { fs.Close(); fs.Dispose(); } } } }
上面演示的作法是沒法經過編譯的。
對於類型的聲明還有一些限制,那就是聲明必需要相互兼容,任何文件都能指定要實現的接口和基類型,以及類型參數的約束。若是多個文件都設定了基類型,那麼它們必須是相同的,而且若是多個文件都設定了類型參數約束,那麼約束必須是一致的。有以下代碼實例:
SegmentType1.cs:
//接口約束:IEquatable<string>; //where TFirst:class :和類型參數約束 partial class SegmentType<TFirst,TSecond>:IEquatable<string> where TFirst:class { //實現IEquatable<string>接口方法 public bool Equals(string other) { return false; } }
SegmentType2.cs
//指定基類:EventArgs //指定接口:IDisposable partial class SegmentType<TFirst, TSecond> :EventArgs,IDisposable { //實現方法 public void Dispose() { } }
以上的接口和基類約束中,也可使用以下方法:
SegmentType1.cs:
//接口約束:IEquatable<string>; //where TFirst:class :和類型參數約束 partial class SegmentType<TFirst,TSecond>:IEquatable<string> where TFirst:class { //實現方法 public void Dispose() { } }
SegmentType2.cs
//指定基類:EventArgs //指定接口:IDisposable partial class SegmentType<TFirst, TSecond> :EventArgs,IDisposable { //實現IEquatable<string>接口方法 public bool Equals(string other) { return false; } }
對於接口和基類型約束能夠進行交換,基於這種特性,能夠將指定的接口與實現分離,將爲不一樣類型生成相同的簽名的方法封裝到一個接口中。沒法在聲明類型時指定其實現了該接口。
以上是主要講解了分部類型的建立和使用方式,接下來咱們再來了解一下分部方法的相關知識。
對於分部方法的相關概念,在前面介紹分部類型時已經作了介紹,分部方法的建立和使用與分部類型相似。分部方法有一個特色:任何對未實現的分部方法的調用,都會被編譯器移除。
分部方法的聲明與抽象方法的申明相似,只須要使用partial修飾符提供簽名而無須任何實現。實現也須要partial修飾符進行修飾。有以下代碼:
SegmentType1.cs:
partial class SegmentType { public SegmentType() { SegmentTypeStart(); Console.WriteLine("分部方法解析..."); SegmentTypeEnd(); } partial void SegmentTypeStart(); partial void SegmentTypeEnd(); }
SegmentType2.cs
partial class SegmentType { partial void SegmentTypeStart() { Console.WriteLine("分部方法開始..."); } }
在分部方法中,因爲方法可能不存在,因此分部方法返回類型必須聲明爲void,且不能獲取out參數。分部方法必須是私有的,可是是靜態的或是泛型。
二.C#分部類型和分部方法的特色:
上面介紹了分部類型和分部方法的定義、建立和使用方式,在這裏主要介紹一下分部方法和分部類型的特色。分部類型主要鏈接設計器和其餘代碼生成器。利用分部類型模型,代碼生成器能夠擁有自由的操做文件,或者只要它願意能夠每次都重寫整個文件。
某些代碼生成器還能夠選擇不生成任何C#文件,而是等到構建進行的時候再生成。代碼生成器的應用比較的普遍,好比Web服務器代理、ORM工具生成配置文件等等。對於在ORM工具的應用有以下圖:
分部類型在其餘方面也有比較多的使用,分部類型能夠輔助咱們進行重構。(重構的第一步就是將比較大的類型分紅較小的類,不少的關聯的內容首先就能夠分割爲在兩個或多個文件上存放的分部類型。)
分部類型也能夠幫助咱們進單元測試。
分部方法能在手動建立的文件中指定某種行爲,並在自動生成的文件中使用該行爲。
分部類型和分部方法是一個語言特性,在這裏給出一個使用了分部類型的項目。https://github.com/fiidau/Phasing-Utility
對於分部類型和分部方法的介紹還有不少,在本文中只是作了一個簡單的介紹,分佈類型的使用也是比較的普遍,能夠極大的提高咱們的代碼質量。但願本文對你們有所幫助。