在C#中所谓泛型其实就是一个不确定的数据类型,可以用在类或方法上;泛型在声明期间无需指定具体数据类型。在编译器编译完成之后会生成一个占位符,当调用者在调用时传入指定的数据类型才会将占位符替换掉。在定义泛型时,可以对泛型参数施加一些限制,这些限制称为泛型约束,泛型约束使用where关键字来实现,每个泛型参数可以具有多个次约束。
名称 | 描述 |
---|---|
T:struct | 类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。 |
T:class | 类型参数必须是引用类型,包括任何类、接口、委托或数组类型。 |
T:new() | 类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,约束必须放在最后。 |
T:基类名 | 类型参数必须是指定的基类或派生自指定的基类。 |
T:接口名 | 类型参数必须是指定的接口或实现指定的接口,可以指定多个接口约束,约束接口也可以是泛型的。 |
T:U | 当泛型类型参数用作约束时,我们称之为裸类型约束。 |
struct&class基类约束
指出某个类型必须将指定的类作为基类或者就是该类本身,才能用作该泛型类型的类型参数。这样的约束一经使用,就必须出现在该类型参数的所有其他约束之前。
//约束T1基类为结构体,约束T2基类为类
public class CiSharp<T1, T2> where T1 : struct where T2 : class
{
public T1 TestT1;
public T2 TestT2;
}
接口约束
约束类型参数T1需要实现 IComparable
//接口约束
public class CiSharp<T1, T2> where T1 : IComparer<T1>
{
public T1 TestT1;
public T2 TestT2;
}
new()约束
new约束也成为构造函数约束,new()的含义是被约束的泛型参数必须具有可访问的无参数或默认构造函数,并且new() 约束必须出现在where最后。
//构造函数约束
public class CiSharp<T1, T2> where T2 :class, new()
{
public T1 TestT1;
public T2 TestT2;
}
裸类型约束
当泛型类型参数用作约束时,我们称之为裸类型约束。
//裸类型约束
public class CiSharp<T> where T : class, new()
{
public T TestT1;
public void CiSharpTest<U>(U entity) where U : T
{
}
}