最近狀態有點不對,所以就沒有去更新筆記,塔防游戲也沒繼續開發,等調整好狀態再繼續塔防游戲。
先做一些筆記找找感覺,估計是真的老了,內分泌失調,各種不順心。。。
繼續關于泛型的記錄,上一篇中記錄了一些在MSDN中學習到的泛型簡介,但是并沒有很清楚的介紹出泛型的功能作用是什么?
也就是,我們能用泛型來做些什么東西?
那么,來介紹一下泛型的一個具體的功能。
當我們需要對int類型的變量進行處理時,我們寫一個處理int類型的方法或者類,這是很正常的現象,也是低級程序猿都會做的事情,
但是對于程序猿中的老司機就不會這樣去考慮了,他會考慮,以后會不會對float類型,string類型,或者自定義類型的變量做相同的處理操作?這樣的話,只是單純的去寫一個int類型的處理函數或者類,對以后的可擴展性幾乎為0,而且還跟小白程序猿寫一樣的東西,太lowB了,要寫就要寫一些高深的,讓人看不懂的,這才彰顯老司機的身份。那么我能不能寫一個通用類型的處理函數或者類?
老司機果然就是老司機,遠遠不是小白可以比擬的?。?!
但是有人可能會想到,如果要做一個通用的類型,那么在C#中所有的類型都是繼承自Object類型,寫一個Object類型的處理方法或者類不就好了?
的確,這是一個解決方法,看起來也很完美。
但是,但是,但是,不要忘記:裝箱與拆箱(裝箱:將類型轉換成object類型,拆箱:將object類型轉換成需要的類型)。
當你需要處理大量的值類型數據的時候,頻繁的進行裝箱與拆箱,那就是傻逼的行為了,請原諒我用了傻逼這個詞,但是我控制不住自己?。?br>
雖然處理大量的引用類型不需要裝箱與拆箱,但是頻繁的進行強轉也是一個負擔。
但是,如果老司機要這樣去寫一個通用類型的處理方法或者類,他就會用到泛型!?。?/p>
泛型用一個通過的數據類型T來代替object,在類實例化時指定T的類型,運行時(Runtime)自動編譯為本地代碼,運行效率和代碼質量都有很大提高,并且保證數據類型安全。
其實,也就是說,我們先用一個“身份模糊”的類型來搭建模板,然后在遇到具體事件的時候,將這個模板的類型身份根據具體事件而確定下來,這就是泛型的方便之處。
因為本篇記錄的是泛型類,所以,來一個泛型類的代碼:
比如,我們需要一個處理數據存儲的類,可能會存儲int類型,float類型等。
C#中數據類型有兩大類:引用類型和值類型。值類型一般是非nullable的值類型,如int, long, struct等,在泛型的約束中,我們也可以大范圍地限制類型T必須是引用類型或必須是值類型,分別對應的關鍵字是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);
}
當然,你可以把int類型變成float,但是在實例化時,要注意格式問題,別忘記尖括號。
那么從泛型類到一個具體的類型,中間是如何轉換的呢?
其實,C#在編譯泛型類時,是先會生成中間代碼IL,通用類型T只是一個占位符,在進行指定具體類型時,將由用戶指定的具體類型代替通用類型T并由即時編譯器(JIT)生成本地代碼,此時這個本地代碼中的類型已經是用戶指定的具體類型了,后面的過程其實就是針對這個具體類型進行操作了,就跟我們的通用類型模板已經沒關系了。
也就是說:DataSave<int> 與 DataSave<float> 是兩個完全沒有任何關系的類型。
關于,針對通用類型T的約束,就是上一篇中記錄的那樣,使用where關鍵字進行約束,約束的方式是指定T的祖先,即繼承的接口或類。因為C#的單根繼承性,所以約束可以有多個接口,但最多只能有一個類,并且類必須在接口之前。
但是,通用類型是無法用運算符進行大小比較的,那么這怎么解決呢?
通過繼承IComparable接口來實現。
當然,你也可以定義多個類型參數和約束,比如這樣:
public class Base<T,U,V> where T : struct
where U : new()
where V : class
{ }
在編寫我們自己的泛型類型的時候,可以通過繼承接口來實現一些我們知道的需要的方法。
泛型類是一個很方便的技術,極大的方便了代碼重用,以及如何優雅的解決一些復用代碼的問題。
泛型類型記錄到這里,下面會記錄一些泛型類型中的一些成員。