今天的文章是因為再給一個朋友講這個的時候隨手記錄下整理出來的。說白了就是把前輩們曾經給我吹過的我又吹了出去。 泛型:是C# FrameWork 2.0 時代 加入進來的,可以說對與Net開發人員來說泛型是無處不再的,喜歡看源碼的同學,可能會有發現,包括MVC裡面基本上也是有很多發泛型,還有很多設計模 ...
今天的文章是因為再給一個朋友講這個的時候隨手記錄下整理出來的。說白了就是把前輩們曾經給我吹過的我又吹了出去。
泛型:是C# FrameWork 2.0 時代 加入進來的,可以說對與Net開發人員來說泛型是無處不再的,喜歡看源碼的同學,可能會有發現,包括MVC裡面基本上也是有很多發泛型,還有很多設計模式也需要搭配泛型來實現,包括項目架構
泛型的存在,是代碼利用率復用性都大大的提升了,有時候Object 也是可以起到相同的作用,為什麼使用泛型 為什麼不是用Obj ,我們來看一下:
下麵我們列出兩個最基礎的方法:
/// <summary> /// 返回int /// </summary> /// <param name="I"></param> /// <returns></returns> public int ShowInt(int I) { return I; } /// <summary> /// 返回String /// </summary> /// <param name="I"></param> /// <returns></returns> public string ShowString (string I) { return I; }
上面的兩個方法自從參數 進來到參數出去的這一個過程中我們沒有進行參數方面的轉換,也就是說單純的針對的參數類型上面我們程式代碼是沒有損失任何的性能的。一位沒有存在拆箱裝箱的過程。
我們在看兩個方法:我們使用了在C# 1.0 時代就存在的一個類型 是Object
/// <summary> /// 返回int /// </summary> /// <param name="I"></param> /// <returns></returns> public int ShowString(object I) { return Convert.ToInt32(I); } /// <summary> /// 返回String /// </summary> /// <param name="I"></param> /// <returns></returns> public string ShowString(object I) { return I.ToString(); }
這裡我們使用的闡述類型是Obj ,Object 是引用類型,也是所有類型的父類,可以包容所有的類型,但是就單說處理參數類型的時候我們需要去轉換一下才能進行使用,在這個轉換的過程中我們已經損失了性能,但是使用Obj 的時候我們可以和成一個方法減少代碼量,提升了代碼的復用率。
比如:
/// <summary> /// 返回object /// </summary> /// <param name="I"></param> /// <returns></returns> public object ShowType(object I) { return I; }
現在簡寫成為這樣後,我們是一個公用的方法:雖然說內部不用去轉換了但是,在調用後,還是需要類型的轉換同樣的需要損失性能。中間性能之所以會損失是因為Obj是引用類型,存放在堆上的,假如說我們傳的參數是int或其他的值類型來使用我們的公共方法,就會進行一次包裝的過程,把存放在棧裡面的值類型移動包裝成為引用類型存放到堆裡面,使參數符合當前方法的類型,這個過成也就是裝箱(需要重新分配記憶體),但是我們在使用的時候,又需要把他拿出來進行一下裝換轉換為值類型,這個過程又稱為拆箱,
我們在來使用一個方法:使用 2.0時代出現的泛型:
/// <summary> /// 返回 T /// </summary> /// <param name="Parameter"></param> /// <returns></returns> public T Show<s>(T Parameter) { return Parameter; }
為什麼會使用泛型 是因為泛型方法再調用的時候有延時聲明的功能這裡的延時聲明式只參數,泛型裡面的 T ,其實咱們也可以理解為 占位符具體為誰占位的,等到調用的時候才會知道。
如下:
int parameter = 0; //在調用的時候聲明參數類型 parameter = new Common().Show<int>(parameter); //如果調用的時候不去聲明的話,JIT編譯的時候野會幫我們自動計算 parameter = new Common().Show(parameter);
這個時候不會損耗什麼性能。延時聲明也是咱們在進行框架設計的時候常用的一種思想,提高框架的性能。泛型不只是可以聲明泛型方法:
泛型類:
/// <summary> /// CURD 操作類 /// </summary> /// <typeparam name="T"></typeparam> public class ConmonClass<T> { public void Add(T s) { }; public void Update(T s) { }; public void Del(T s) { }; public void Select(T s) { }; }
這樣使用的話,在咱們真正的項目,我們可以把某些基礎的操作用一個類去搞定,使用的時候調用就是了,減少代碼的冗餘,增加復用性,重用率。
泛型介面:
/// <summary> /// CURD 操作介面類 /// </summary> /// <typeparam name="T"></typeparam> public interface ConmonInterface<T> { T Add(T s); T Update(T s); T Del(T s); T Select(T s); }
泛型委托:
//泛型委托 public delegate T GetHandler<T>();
我想以上的操作在我們開發項目的時候會經常見到,或使用到
以上代碼需要我們註意的時候,泛型類不能被繼承,如果想要繼承的話需要在繼承的時候,給我們的不確定參數確定下參數類型。包括泛型介面也是一樣的。
如下:
public class Son : ConmonClass<Common> {}; /// <summary> /// 實現泛型介面 /// </summary> public class SonInterface : ConmonInterface<Common> { public Common Add(Common s) { throw new NotImplementedException(); } public Common Del(Common s) { throw new NotImplementedException(); } public Common Select(Common s) { throw new NotImplementedException(); } public Common Update(Common s) { throw new NotImplementedException(); } }
如果說不指定泛型類型的參數類型式其實我們一樣是可以繼承的。需用繼承者同樣是泛型的。
建議:長期使用Net的同學我想我們需要加強一下泛型的認識了,因為在NetCore中常常會使用依賴註入,在使用泛型類的時候我們可能會多少有點麻煩的,泛型方法相對來說要簡單的,如果說要想讓我們的框架實現高度的內聚,大家需要多多理解。
泛型的約束,多重約束相當重要,代表我們是否能很好的利用泛型。
泛型的約束類型大概分為如下幾種:
引用類型約束: |
表明泛型參數只能是引用類型的: |
值類型約束: |
表明泛型參數只能是值類型的: |
無參數構造函數約束: |
泛型是可以實例化的。 |
基類約束 |
必須滿足基類中的某些屬性 |
介面約束 |
必須滿足介面中的某些屬性 |
具體的就不代碼了。
有不足之處 希望大家指出相互學習,
本文原創:轉載請註明出處 謝謝!