泛型類別條件約束(generic class constraint)
用來指定泛型型別參數的約束條件,限制它必須是特定的型別或符合某些條件。
指定泛型型別參數必須繼承自特定的基底類別或介面
1
2
3
4public class MyClass<T> where T : MyBaseClass
{
// MyClass<T> 的程式碼
}MyClass
泛型類別指定了泛型型別參數 T 必須繼承自 MyBaseClass 基底類別。這樣一來,在定義 MyClass 物件時,T 的型別必須符合這個條件,否則就會編譯錯誤。 指定泛型型別參數必須是值型別或可為空的值型別
1
2
3
4
5public class MyClass<T> where T : struct
{
// MyClass<T> 的程式碼
}MyClass
泛型類別指定了泛型型別參數 T 必須是值型別或可為空的值型別。這樣一來,在定義 MyClass 物件時,T 的型別必須符合這個條件,否則就會編譯錯誤。 指定泛型型別參數必須有預設的建構函式
1
2
3
4
5public class MyClass<T> where T : new()
{
// MyClass<T> 的程式碼
}MyClass
泛型類別指定了泛型型別參數 T 必須有預設的建構函式。這樣一來,在定義 MyClass 物件時,T 的型別必須符合這個條件,否則就會編譯錯誤。
實際例子
LINQ 擴充方法
在 LINQ 擴展方法中,常常需要使用 IEnumerable接口的功能。但是有些類型並沒有實現 IEnumerable 接口,這時就可以使用泛型類約束來保證傳入的類型必須實現該接口: 1
2
3
4
5
6
7
8
9
10
11
12public static class MyExtension
{
public static int Count<T>(this T[] arr) where T : IEnumerable
{
int count = 0;
foreach (var item in arr)
{
count += item.Count();
}
return count;
}
}上方範例要統計數組中所有元素的數量,因為無法確定傳入的數組類型是否實現 IEnumerable 接口,所以使用泛型類約束來限制傳入類型必須實現該接口。
資料庫操作
在資料庫操作中,有時需要使用泛型類來表示數據表,這時就需要使用泛型類約束來保證傳入的泛型類型必須是類類型:
1 | public class DBManager<T> where T : class |
使用泛型類 DBManager
- 重載
有時需要使用泛型類來表示某種類型,這時就需要使用泛型類約束來保證傳入的泛型類型必須實現某種接口或者是某個基類:
1 | public class Vector<T> where T : struct, IComparable<T> |
在上面的例子中,我們定義了一個泛型類 Vector