C# 約束類型
前面用于泛型類的類型稱為無綁定(unbounded)類型,因為沒有對它們進行任何約束。而通過約束(constraining)類型,可以限制用于實例化泛型類的類型,這有許多方式。例如,可以把類型限制為繼承自某個類型。回顧前面使用的Animal、Cow和Chicken類,可以把一個類型限制為Animal或繼承自Animal,則下面的代碼是正確的:
MyGenericClass<Cow> = new MyGenericClass<Cow>();
但下面的代碼不能編譯:
MyGenericClass<string> = new MyGenericClass<string>();
在類定義中,這可以使用where關鍵字來實現(xiàn):
class MyGenericClass<T> where T : coAstraint { ... }
其中constraint定義了約束??梢杂眠@種方式提供許多約束,各個約束之間用逗號分開:
class MyGenericClass<T> where T : constraintl, constraint2 { ... }
還可以使用多個where語句,定義泛型類需要的任意類型或所有類型上的約束:
class MyGenericClass<Tl, T2> where Tl : constraintl where T2 : constraints ( ...)
約束必須出現(xiàn)在繼承說明符的后面:
class MyGenericClass<Tl, T2> : MyBaseClass, IMylnterface where Tl : constraintl where T2 : constraint2 { ... }
下表列出了一些可用的約束。
約束 | 定 義 | 用法示例 |
struct | 類型必須是值類型 | 在類中,需要值類型才能起作用,例如,T類型的成員變量是0,表示 某種含義 |
class | 類型必須是引用類型 | 在類中,需要引用類型才能起作用,例如,T類型的成員變毋是null, 表示某種含義 |
base- class | 類型必須是基類或繼承自基類??梢愿?據(jù)這個約束提供任意類名 | 在類中,貓要繼承自基類的某種基本功能,才能起作用 |
interface | 類型必須是接口或實現(xiàn)了接口 | 在類中,徭要接口公開的某種基本功能,才能起作用 |
new() | 類型必須有一個公共的無參構造函數(shù) | 在類中,需要能實例化T類型的變S,例如在構造函數(shù)中實例化 |
可通過base-class約束,把一個類型參數(shù)用作另一個類型參數(shù)的約束,如下所示:
class MyGenericClass<Tl, T2> where T2 : T1 { ... }
其中,T2必須與T1的類型相同,或者繼承自T1。這稱為裸類型約束(naked type constraint),表示一個泛型類型參數(shù)用作另一個類型參數(shù)的約束。
類型約束不能循環(huán),例如:
class MyGenericClass<Tl, T2> where T2 : T1 where T1 : T2 { ... }
這段代碼不能編譯。
點擊加載更多評論>>