C# 约束类型
前面用于泛型类的类型称为无绑定(unbounded)类型,因为没有对它们进行任何约束。而通过约束(constraining)类型,可以限制用于实例化泛型类的类型,这有许多方式。例如,可以把类型限制为继承自某个类型。回顾前面使用的Animal、Cow和Chicken类,可以把一个类型限制为Animal或继承自Animal,则下面的代码是正确的:
MyGenericClass<Cow> = new MyGenericClass<Cow>();
但下面的代码不能编译:
MyGenericClass<string> = new MyGenericClass<string>();
在类定义中,这可以使用where关键字来实现:
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 ( ...)
约束必须出现在继承说明符的后面:
class MyGenericClass<Tl, T2> : MyBaseClass, IMylnterface where Tl : constraintl where T2 : constraint2 { ... }
下表列出了一些可用的约束。
约束 | 定 义 | 用法示例 |
struct | 类型必须是值类型 | 在类中,需要值类型才能起作用,例如,T类型的成员变量是0,表示 某种含义 |
class | 类型必须是引用类型 | 在类中,需要引用类型才能起作用,例如,T类型的成员变毋是null, 表示某种含义 |
base- class | 类型必须是基类或继承自基类。可以根 据这个约束提供任意类名 | 在类中,猫要继承自基类的某种基本功能,才能起作用 |
interface | 类型必须是接口或实现了接口 | 在类中,徭要接口公开的某种基本功能,才能起作用 |
new() | 类型必须有一个公共的无参构造函数 | 在类中,需要能实例化T类型的变S,例如在构造函数中实例化 |
可通过base-class约束,把一个类型参数用作另一个类型参数的约束,如下所示:
class MyGenericClass<Tl, T2> where T2 : T1 { ... }
其中,T2必须与T1的类型相同,或者继承自T1。这称为裸类型约束(naked type constraint),表示一个泛型类型参数用作另一个类型参数的约束。
类型约束不能循环,例如:
class MyGenericClass<Tl, T2> where T2 : T1 where T1 : T2 { ... }
这段代码不能编译。
点击加载更多评论>>