C# 泛型Generic
泛型(Generic),是將不確定的型別預先定義下來的一種C#高階語法,我們在使用一個類,介面或者方法前,不知道使用者將來傳什麼型別,或者我們寫的類,介面或方法相同的程式碼可以服務不同的型別,就可以定義為泛型。這會大大簡化我們的程式碼結構,同時讓後期維護變得容易。
泛型很適用於集合,我們常見的泛型集合有:List<T>,Dictionary<K,V>等等(T,K,V就代表不確定的型別,它是一種型別佔位符),無一不是利用的泛型這一特性,若沒有泛型,我們會多出很多過載方法,以解決型別不同,但是執行邏輯相同的情況。
自定義泛型:
學會自定義泛型,那麼遇到微軟為我們預先定義好的泛型資料結構也會很容易理解。
支援泛型定義的資料結構有類,介面,方法,委託
定義泛型的方法就是在名稱後新增<T>,T可以是任何字元,可以定義多個泛型<T1,T2...>,只要符合C#命名規範即可,但我們一般用只T,定義以後,在其程式碼塊中的任何位置即可引用這一型別T,我們在用的時候傳入的型別,會替代所有的T,所以不要認為泛型是弱型別,它是強型別的。
下面進行程式碼演示:
public class MyGeneric<T>{...code...}//泛型類 public T GenericMethod<T>{...code...}//泛型方法 interface IGeneric<T>{...code...}//泛型介面 delegate void DeleGeneric<T1,T2>();//泛型委託
default關鍵字:
在switch語句中,用到了default關鍵字,用於匹配case沒捕獲到的情況,在泛型中,由於T可能是值型別也可能是引用型別,我們編碼時無法確定,所以我們無法通過正常形式,將T賦給一個既定的型別,所以有如下語法:
defalut(T);//根據型別被賦值型別,引用型別則返回null,值型別則返回對應的預設值
約束型別:
為了避免使用者隨意使用泛型,我們可以給泛型加約束,約束關鍵字是where,我們可以把泛型設定為必須繼承某個類,或者必須是引用或者值型別(泛型方法也可以設定約束,但顯然有些約束不適合方法,比如繼承某個類,這是類特有的性質),請先看如下程式碼:
class MyGeneric<T> where T:SuperGeneric,new(){...} class MyGeneric<T1,T2> where T1:new() where T2:new(){...} class MyGeneric<T> :IEnumerable where T:SuperGeneric,new(){...}
第一行,指定T,必須繼承SuperGeneric類,而且必須有一個公共無參的構造方法
第二行,分別用where 指定了T1,T2的約束,對於多個泛型型別,新增約束就要這樣寫,一個where對應一個泛型型別
第三行,是個要注意的點,泛型約束要定義在類繼承語法的後面,這是必要的,因為放在where後會引起歧義
約束型別有以下幾個:
注意,new()必須放在約束的最後
泛型在繼承中需要注意的點:
子類繼承泛型,子類泛型的約束不能大於父類約束或者與父類約束衝突,比如父類泛型約束是值型別,那麼子類的泛型約束就不能設定為引用型別。
如果繼承泛型類,那麼子類要麼也是泛型類,要麼顯示指定父類泛型的型別,以下程式碼是錯誤的:
class ChildClass:Ilist<T>{...}//編譯不通過,使用時無法確定T的型別
可以顯示設定,或者設定子類為泛型:
class ChildClass:Ilist<string>{...} class ChildClass<T>:Ilist<T>{...}
這是我的公眾號,獲取最新文章,請關注此號