1. 程式人生 > 實用技巧 >C# 泛型Generic

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>{...}

這是我的公眾號,獲取最新文章,請關注此號