六種類型的約束:html
T:結構編程 |
類型參數必須是值類型。能夠指定除 Nullable 之外的任何值類型。有關更多信息,請參見使用可空類型(C# 編程指南)。數組 |
T:類函數 |
類型參數必須是引用類型,包括任何類、接口、委託或數組類型。spa |
T:new().net |
類型參數必須具備無參數的公共構造函數。當與其餘約束一塊兒使用時,new() 約束必須最後指定。code |
T:<基類名>htm |
類型參數必須是指定的基類或派生自指定的基類。對象 |
T:<接口名稱>blog |
類型參數必須是指定的接口或實現指定的接口。能夠指定多個接口約束。約束接口也能夠是泛型的。 |
T:U |
爲 T 提供的類型參數必須是爲 U 提供的參數或派生自爲 U 提供的參數。這稱爲裸類型約束。 |
例子:
1.接口約束。
例如,能夠聲明一個泛型類 MyGenericClass,這樣,類型參數 T 就能夠實現 IComparable<T> 接口:
public class MyGenericClass<T> where T:IComparable { }
2.基類約束。
指出某個類型必須將指定的類做爲基類(或者就是該類自己),才能用做該泛型類型的類型參數。這樣的約束一經使用,就必須出如今該類型參數的全部其餘約束以前。
class MyClassy<T, U> where T : class where U : struct { }
3.構造函數約束。
以使用 new 運算符建立類型參數的實例;但類型參數爲此必須受構造函數約束 new() 的約束。new() 約束可讓編譯器知道:提供的任何類型參數都必須具備可訪問的無參數(或默認)構造函數。new() 約束出如今 where 子句的最後。
public class MyGenericClass <T> where T: IComparable, new() { // The following line is not possible without new() constraint: T item = new T(); }
4.對於多個類型參數,每一個類型參數都使用一個 where 子句。
interface MyI { } class Dictionary<TKey,TVal> where TKey: IComparable, IEnumerable where TVal: MyI { public void Add(TKey key, TVal val) { } }
5.還能夠將約束附加到泛型方法的類型參數。
public bool MyMethod<T>(T t) where T : IMyInterface { }
6. 裸類型約束
用做約束的泛型類型參數稱爲裸類型約束。當具備本身的類型參數的成員函數須要將該參數約束爲包含類型的類型參數時,裸類型約束頗有用。
class List<T> { void Add<U>(List<U> items) where U : T {/*...*/} }
泛型類的裸類型約束的做用很是有限,由於編譯器除了假設某個裸類型約束派生自 System.Object 之外,不會作其餘任何假設。在但願強制兩個類型參數之間的繼承關係的狀況下,可對泛型類使用裸類型約束。
7.default關鍵字
之因此會用到default關鍵字,是由於須要在不知道類型參數爲值類型仍是引用類型的狀況下,爲對象實例賦初值。考慮如下代碼:
class TestDefault<T> { public T foo() { T t = null; //??? return t; } }
若是咱們用int型來綁定泛型參數,那麼T就是int型,那麼註釋的那一行就變成了 int t = null;顯然這是無心義的。爲了解決這一問題,引入了default關鍵字:
class TestDefault<T> { public T foo() { return default(T); } }
參考:http://www.jb51.net/article/37658.htm
http://www.cnblogs.com/ottox/archive/2009/03/02/1401307.html
http://www.jb51.net/article/41143.htm