最近狀態(tài)有點不對笆环,所以就沒有去更新筆記攒至,塔防游戲也沒繼續(xù)開發(fā),等調(diào)整好狀態(tài)再繼續(xù)塔防游戲躁劣。
先做一些筆記找找感覺迫吐,估計是真的老了,內(nèi)分泌失調(diào)账忘,各種不順心志膀。熙宇。。
繼續(xù)關(guān)于泛型的記錄溉浙,上一篇中記錄了一些在MSDN中學(xué)習(xí)到的泛型簡介烫止,但是并沒有很清楚的介紹出泛型的功能作用是什么?
也就是戳稽,我們能用泛型來做些什么東西馆蠕?
那么,來介紹一下泛型的一個具體的功能惊奇。
當(dāng)我們需要對int類型的變量進行處理時互躬,我們寫一個處理int類型的方法或者類跟啤,這是很正常的現(xiàn)象新博,也是低級程序猿都會做的事情,
但是對于程序猿中的老司機就不會這樣去考慮了恩溅,他會考慮乓序,以后會不會對float類型寺酪,string類型,或者自定義類型的變量做相同的處理操作竭缝?這樣的話房维,只是單純的去寫一個int類型的處理函數(shù)或者類沼瘫,對以后的可擴展性幾乎為0抬纸,而且還跟小白程序猿寫一樣的東西,太lowB了耿戚,要寫就要寫一些高深的湿故,讓人看不懂的,這才彰顯老司機的身份膜蛔。那么我能不能寫一個通用類型的處理函數(shù)或者類坛猪?
老司機果然就是老司機,遠遠不是小白可以比擬的T砉伞J浴!
但是有人可能會想到呜呐,如果要做一個通用的類型就斤,那么在C#中所有的類型都是繼承自O(shè)bject類型,寫一個Object類型的處理方法或者類不就好了蘑辑?
的確洋机,這是一個解決方法,看起來也很完美洋魂。
但是绷旗,但是喜鼓,但是,不要忘記:裝箱與拆箱(裝箱:將類型轉(zhuǎn)換成object類型衔肢,拆箱:將object類型轉(zhuǎn)換成需要的類型)庄岖。
當(dāng)你需要處理大量的值類型數(shù)據(jù)的時候,頻繁的進行裝箱與拆箱角骤,那就是傻逼的行為了顿锰,請原諒我用了傻逼這個詞,但是我控制不住自己捌袈А硼控!
雖然處理大量的引用類型不需要裝箱與拆箱,但是頻繁的進行強轉(zhuǎn)也是一個負擔(dān)胳赌。
但是牢撼,如果老司機要這樣去寫一個通用類型的處理方法或者類,他就會用到泛型R缮弧Q妗!
泛型用一個通過的數(shù)據(jù)類型T來代替object捍掺,在類實例化時指定T的類型撼短,運行時(Runtime)自動編譯為本地代碼,運行效率和代碼質(zhì)量都有很大提高挺勿,并且保證數(shù)據(jù)類型安全曲横。
其實,也就是說不瓶,我們先用一個“身份模糊”的類型來搭建模板禾嫉,然后在遇到具體事件的時候,將這個模板的類型身份根據(jù)具體事件而確定下來蚊丐,這就是泛型的方便之處熙参。
因為本篇記錄的是泛型類,所以麦备,來一個泛型類的代碼:
比如孽椰,我們需要一個處理數(shù)據(jù)存儲的類,可能會存儲int類型凛篙,float類型等黍匾。
C#中數(shù)據(jù)類型有兩大類:引用類型和值類型。值類型一般是非nullable的值類型鞋诗,如int, long, struct等膀捷,在泛型的約束中,我們也可以大范圍地限制類型T必須是引用類型或必須是值類型削彬,分別對應(yīng)的關(guān)鍵字是class和struct:
public class DataSave<T> where T:struct
{
private T data;
private T des;
public DataSave(T data){
this.data=data;
}
public T _Des{
set{des=value;}
get{return des;}
}
public void SaveData(List<T> list,T data){
list.add(data);
}
}
然后全庸,我們就可以這樣用了秀仲。
static void Main(string args[])
{
List<int> intDataList = new List<int>();
DataSave<int> intData = new DataSave<int>(100);
intData.SaveData(intDataList,intData.data);
}
當(dāng)然,你可以把int類型變成float壶笼,但是在實例化時神僵,要注意格式問題,別忘記尖括號覆劈。
那么從泛型類到一個具體的類型保礼,中間是如何轉(zhuǎn)換的呢?
其實责语,C#在編譯泛型類時炮障,是先會生成中間代碼IL,通用類型T只是一個占位符坤候,在進行指定具體類型時胁赢,將由用戶指定的具體類型代替通用類型T并由即時編譯器(JIT)生成本地代碼,此時這個本地代碼中的類型已經(jīng)是用戶指定的具體類型了白筹,后面的過程其實就是針對這個具體類型進行操作了智末,就跟我們的通用類型模板已經(jīng)沒關(guān)系了。
也就是說:DataSave<int> 與 DataSave<float> 是兩個完全沒有任何關(guān)系的類型徒河。
關(guān)于系馆,針對通用類型T的約束,就是上一篇中記錄的那樣顽照,使用where關(guān)鍵字進行約束由蘑,約束的方式是指定T的祖先,即繼承的接口或類棒厘。因為C#的單根繼承性纵穿,所以約束可以有多個接口下隧,但最多只能有一個類奢人,并且類必須在接口之前。
但是淆院,通用類型是無法用運算符進行大小比較的何乎,那么這怎么解決呢?
通過繼承IComparable接口來實現(xiàn)土辩。
當(dāng)然支救,你也可以定義多個類型參數(shù)和約束,比如這樣:
public class Base<T,U,V> where T : struct
where U : new()
where V : class
{ }
在編寫我們自己的泛型類型的時候拷淘,可以通過繼承接口來實現(xiàn)一些我們知道的需要的方法各墨。
泛型類是一個很方便的技術(shù),極大的方便了代碼重用启涯,以及如何優(yōu)雅的解決一些復(fù)用代碼的問題贬堵。
泛型類型記錄到這里恃轩,下面會記錄一些泛型類型中的一些成員。