學習了型別,可以知道型別的實質是物件的模板,而泛型實質就是型別的模板
。
泛型允許宣告型別引數化的**,即可以使用型別佔位符來定義泛型,然後在建立類的例項是指明真實的型別。
c#提供五種泛型:
前四種是型別,而方法是成員。
建立和使用非泛型類有兩個步驟:
而使用泛型這需要多乙個步驟,就是使用泛型構建實際的型別,構建之後的型別稱為構造型別,然後就像使用非泛型一樣,建立這個構建後的型別的例項。
宣告乙個簡單的泛型類與宣告非泛型類差不多,區別是:
例如:
class someclass
建立構造型別很簡單,只需提供真實型別替代在尖括號中的型別引數,而這些真實型別又稱為型別實參。
泛型建立例項的形式和非泛型類幾乎一樣,例如:
// 非泛型
mynongenclass myngc = new mynongenclass();
// 泛型
someclass mysc1 = new someclass();
var mysc2 = new someclass(); // 同樣可以使用 var 關鍵字
someclass mysc3;
mysc3 = new someclass(); // 和非泛型一樣,引用和例項可以分開建立
在泛型主體**中若嘗試不是object
類的成員**(因為所有型別都派生自object
類),編譯器會產生乙個錯誤資訊。
要讓泛型變得更有用,就在定義泛型的時候需要提供額外的資訊讓編譯器知道引數可以接受哪些型別,這些額外的資訊就叫做約束。
約束使用where
子句表示:
例如:
class myclass where t2: int
where t1: string, int
// where 子句不需要使用分隔符
約束型別共有五種:
其中where
子句最多只能有乙個主約束,且必須放置在第一位;可以有任意多介面名約束;如果存在建構函式約束,這必須放置在最後。
與其他泛型不一樣,方法是成員不是型別,所以泛型方法可以在以下情況下宣告:
泛型方法的宣告有兩個引數列表:
- 型別引數列表,放置在方法名稱之後
- 方法引數列表,放置在型別引數列表之後(方法引數列表後可緊接約束子句)
例如:
public void printdatat> (s p, t t) where s: person
同樣的,泛型方法也可以運用到 擴充套件方法 中定義泛型委託有點要注意的就是型別引數的範圍了,與泛型方法相似,型別引數位於委託名稱之後,委託引數列表之前的尖括號中。
其中委託的型別引數的內容可以包括:
例如:
public
delegate trr func(t1 p1, t2 p2); // 其中 t1,t2 為形參,而 tr 為返回值型別
建立泛型介面與非泛型介面類似,都是宣告介面,然後實現介面,例如:
// 宣告介面
inte***ce
imyifc
// 實現介面
class
******
: imyifc
}class
program
", trivint.returnit(5));
console.writeline("", trivstring.returnit("hi there"));
}}
注意:
協變out
與逆變in
只適合用於委託和介面,其實現都是根據賦值的相容性。
out
的實現就是因為:呼叫**獲得乙個指向其基類引用(派生類 => 基類)
in
的實現就是因為:被呼叫**收到乙個基類引用(基類 => 派生類)
C 學習筆記 泛型
泛型將型別引數的概念引入了.net,當我們需要設計類和方法,並將它們的型別制定推遲到客戶端 宣告,並例項化該型別和方法時,可以使用泛型。泛型使之前的想法成為了可能。使用泛型避免了執行時強制轉換或裝箱操作帶來的風險。簡單來說,首先制定乙個特定符號代替實際型別,當建立該型別的例項時,才指定它的實際型別。...
C 筆記 List 泛型
所屬命名空間 system.collections.generic list類是 arraylist 類的泛型等效類。該類使用大小可按需動態增加的陣列實現 ilist 泛型介面。泛型的好處 它為使用c 語言編寫物件導向程式增加了極大的效力和靈活性。不會強行對值型別進行裝箱和拆箱,或對引用型別進行,向...
C 泛型學習筆記
泛型概述 使用泛型型別可以最大限度地重用 保護型別的安全以及提高效能。泛型最常見的用途是建立集合類。net framework 類庫在 system.collections.generic 命名空間中包含幾個新的泛型集合類。應盡可能地使用這些類來 代替普通的類,如 system.collection...