C#泛型约束分为:基类约束、接口约束、struct/class约束(值类型/引用类型约束)和构造器约束,另外还有一种where T:U,指定类型实参T必须是类型实参U或者是U的派生类,称之为裸类型约束。where子句之间没有顺序,但where内部各种类型约束之间有次序要求,依次为:基类型/struct/class类型、接口类型、构造器类型。
基类约束和接口约束的语法较为简单:where T:基类名/接口名
struct约束有一个非常特别的地方。一方面它规定类型参数只能为值类型,另一方面,它禁止将System.Nullable<T>作为类型参数。因为定义一个可空的“可空类型”是没有意义的。
并非所有参数都保证有公共默认构造器,所以编译器不允许为类型参数调用默认构造器。为了改变编译器的这一限制,可以指定了其他约束后添加new()。这就是所谓的构造器约束,它指定类型参数必须有一个默认构造器,只能对默认构造器进行约束,不能为带参数的构造器指定约束。
约束进行了一些适当的限制以避免产生无意义的代码。例如,不能将一个基类约束与一个struct/class约束合并到一起,不能为一个struct类型约束使用Nullable<T>,另外,你不能限制从一些特殊的类型继承,比如object,数组,System.ValueType,System.Enum(enum),System.Delegate,System.MulticastDelegate.