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