CLR via C#:泛型

泛型:是CLR和編程語言提供的一種特殊機制,它支持另外一種形式的代碼複用(即算法複用)。具有以下特性:
1.泛型的優點具有源代碼保護(不用公開泛型源代碼),類型安全(必須指定類型實參),更清晰的代碼和更佳的性能(避免類型轉換以及裝箱拆箱等過程)。
2.CLR允許創建泛型引用類型,泛型結構體值類型,泛型接口,泛型委託和泛型函數。
3.C#約定泛型類型參數名至少是以T開頭,如T,TKey,TValue,TEventArgs等。
4.具有泛型類型參數的類型叫做開放類型。該類型是不能創建對象的,並且可以在靜態構造函數裏面限制類型實參。參考代碼如下所示:

internal sealed class GenericTypeThatRequireAnEnumType<T>
{
	// 在靜態構造函數中限制類型實參必須是枚舉類型
	static GenericTypeThatRequireAnEnumType()
	{
		if (!typeof(T).IsEnum)
		{
			throw new ArgumentException("T Must Be A Enum Type");
		}
	}
}

5.所有的泛型類型參數都指定了類型實參的類型叫做封閉類型。該類型是可以創建對象的,並且不同的封閉類型會獨自擁有一份開放類型中所有的成員。
6.爲泛型類型參數指定類型實參並不會改變繼承層次結構。
7.在相同的AppDomain中,當不同程序集中含有同名泛型函數且該函數具有相同泛型類型實參時,CLR只會生成同一份函數代碼。
8.在同名泛型函數中,如果泛型類型實參爲引用類型的話,CLR會生成同一份函數代碼;如果泛型類型實參爲值類型的話,CLR會爲每個值類型都生成一份函數代碼。
9.不指定類型參數的形式調用泛型函數時,編譯器會根據類型實參推斷調用匹配的泛型函數。

泛型類型同一性:就是簡化的類型和封閉類型必須是等價的。具有以下方案:
1.使用using指令來將封閉類型起個別名,此時別名對應的類型就是封閉類型。
2.使用var定義變量來推斷實例的封閉類型,此時變量對應的類型就是封閉類型。

泛型類型參數的種類:如下所示:
1.不變量:意味着泛型類型參數不能更改。
2.逆變量:意味着泛型類型參數可以從一個類更改爲它的某個派生類。具有以下特性:
1>.泛型類型參數不能爲值類型。
2>.C#中用in關鍵字來標記泛型類型參數。
3>.泛型類型參數只能出現在輸入位置,比如作爲函數的參數(參數不能用ref或者out關鍵字)。
3.協變量:意味着泛型類型參數可以從一個類更改爲它的某個基類。具有以下特性:
1>.泛型類型參數不能爲值類型。
2>.C#中用out關鍵字來標記泛型類型參數。
3>.泛型類型參數只能出現在輸出位置,比如作爲函數的返回類型。

約束:指的通過where關鍵字進行限制能指定成泛型類型實參的數量。具有以下特性:
1.約束可以應用於泛型類型和泛型函數。
2.泛型函數重載跟參數列表中每個參數類型有關,跟泛型類型參數名稱以及約束無關。
3.不能指定重寫泛型函數的約束,該函數的約束從基函數繼承。
4.泛型類型參數可以指定0個或者1個主要約束。具有以下特性:
1>.主要約束類型默認爲System.Object類型。
2>.主要約束類型不能爲密封的引用類型。當主要約束類型是非密封的引用類型時,泛型類型實參只能是約束類型或者其派生類型。並且不能指定System.Object,System.Array,System.Delegate,System.MulticastDelegate,System.ValueType,System.Enum,System.Void等引用類型作爲主要約束類型。
3>.當主要約束爲class時,表示泛型類型實參可以爲所有引用類型。
4>.當主要約束爲struct時,表示泛型類型實參可以爲除了Nullable類型外的所有值類型。
5.泛型類型參數可以指定0個或者多個次要約束。具有以下特性:
1>.次要約束用於接口類型時,表示泛型類型實參必須實現該接口。
2>.次要約束用於泛型類型參數時,表示泛型類型實參要麼是約束的類型,要麼是該類型的派生類型。如

// T是由泛型類型參數TBase約束,那麼T久只能是TBase或者其派生類型。
private static List<TBase> ConvertList<T, TBase>(IList<T> list) where T:TBase;

6.泛型類型參數可以指定0個或者1個構造函數約束。具有以下特性:
1>.構造函數約束只能應用公共無參構造函數。
2>.構造函數約束不能和struct主約束一起使用。
3>.構造函數約束表明泛型類型實參是有提供公共無參構造函數的非抽象類型。

可驗證性:具有以下特性:
1.當將泛型類型變量轉型爲泛型約束兼容的類型時,轉換操作是合法;否則就是非法。
2.當主約束類型是非密封的引用類型時,將泛型類型變量設爲null是合法;否則就是非法。
3.當主約束類型不是struct時,將泛型類型變量與null進行比較是合法;否則就是非法。
4.當主約束是非密封的引用類型或者class類型時,將兩個泛型類型變量進行比較是合法,否則就是非法。
5.不能向泛型類型變量應用任何操作符。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章