拆箱和裝箱
從值類型轉換爲引用類型爲裝箱
,把引用類型轉換爲值類型爲拆箱
函數
裝箱和拆箱很容易使用,可是性能損失比較大,尤爲是遍歷許多項的時候。性能
List<T>
不使用對象,在使用時定義類型this
var list = new List<int>(); list.Add(44); // no boxing int item = list[0]; // mo unboxing
不妨將
List<T>
看作一種新的類型,不在特地的和C++的模板相比較;code
T
做爲前綴;泛型類型容許使用任意類替代,且只使用了一個泛型類型就能夠用T
做爲泛型類型的名稱對象
public class List<T>{} public class LinkedList<T>{}
若泛型類型有特定需求(例如必須實現一個接口或派生自基類),或者使用了兩個或多個泛型類型
繼承
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e); public delegate TOutput Converter<TInput, TOutput>(TInput from); public class SOrtedList<TKey, TValue>{}
# 泛型類的功能
## 默認值接口
建立泛型時,不能把null賦予泛型類型 ;在這個時候,咱們就須要
default
,將null
賦予引用類型,0賦值於值類型;string
public T GetDocument() { T doc = default(T); lock(this) { doc = documentQueue.Dequeue(); } return doc; }
## 約束it
若泛型類須要調用泛型類型中的方法,就必須添加約束
where
table
泛型支持如下幾種約束類型:
約束 | 說明 |
---|---|
where T: struct | 對於結構約束,T必須是值類型 |
where T: class | T必須是引用類型 |
where T: IFoo | T必須實現接口IFoo |
where T: Foo | T 必須派生基類Foo |
where T: new() | 構造函數約束,T必須有一個默認構造函數 |
泛型類型也能夠合併多個約束,where T: IFoo, new()
約束和MyMerge<T>
申明指定,T必須實現IFoo接口,且必須有一個默認構造函數,示例以下所示:
public class MyMerge<T> where T: IFoo, new() { // dosomething }
泛型類型能夠實現泛型接口,也能夠派生自類,固然也能夠派生自泛型基類;
public class Base<T>{} public class Derived<T>: Base<T> {} // 派生自泛型基類
固然,泛型類型派生自指定基類的類型:
public class Base<T>{} public class Derived<T>: Base<string>{}
泛型類的靜態成員只能在類的一個實例中共享
// 定一個泛型類的靜態成員 public class StaticDemo<T> { public static int x; } StaticDemo<int>.x = 3; // 第一組靜態字段 = 3 StaticDemo<string>.x = 4; // 第二組靜態字段 = 4 Console.WriteLine(StaticDemo<int>.x); // 這裏將會輸出3
# 泛型接口
使用泛型能夠定義接口,在接口定義的方法能夠帶泛型參數
在.Net中,參數類型是
協變
的
例如,有Shape和Circle類,Circle派生自Shape,Display方法是爲了接受Shape類型的參數
public void Display(Shape object){}
如今能夠傳遞派生自Shape基類的任意對象,例如Circle,Rectangle
Circle c = new Circle(5); Display(c); // 這裏即是協變
方法的返回類型是
抗變
的
例如,若方法返回一個Shape,就不能把它賦予Circle,可是反過來就能夠;
若泛型類型使用
out
標註,泛型接口就是協變
的,意味着返回類型也是T
若泛型類型使用in
標註,泛型接口就是抗變
的,代表傳入的參數類型只能是T