分析问题
当一个泛型参数没有任何约束时,它可以进行的操作和运算是非常有限的,因为不能对实参做任何类型上的保证,这时候就需要用到泛型的约束。泛型的主要约束和次要约束都是指泛型的实参必须满足一定的规范,C#编译器在编译的过程中可以根据约束来检查所有泛型类型的实参并确保其满足约束条件。
一个泛型参数可以至多拥有一个主要约束,主要约束可以是一个引用类型、class或者struct。如果指定一个引用类型,则实参必须是该类型或者该类型派生类型。class规定实参必须是一个引用类型。struct规定了参数必须是一个之类新。以下代码是泛型参数主要约束的示例。
using System;
namespace Test
{
class GenericPrimaryConstraint
{
static void Main()
{
Console.Read();
}
}
//主要约束限定T继承自Exception类型
public class ClassT1<T> where T : Exception
{
private T myException;
public ClassT1(T t)
{
myException = t;
}
public override string ToString()
{
//主要约束保证了myException拥有Source成员
return myException.Source;
}
}
//主要约束限定T是引用类型
public class ClassT2<T> where T : class
{
private T myT;
public void Clear()
{
//T是引用类型,可以置null
myT = null;
}
}
//主要约束限定T是值类型
public class ClassT3<T> where T : struct
{
private T myT;
public override string ToString()
{
//T是值类型,不会发生NullReferenceException异常
return myT.ToString();
}
}
}
以上代码,泛型参数具备了主要约束后,就能够在类型中对其进行一定的操作,否则任何算法就只能基于一个System.Object类型的成员。
可以说,主要约束是实参类型的限定,而相对的次要约束,则是指实参实现的接口的限定。对于一个泛型类型,可以有0至无限的次要约束,次要约束规定了参数必须实现所有次要约束中规定的接口。次要约束的语法和主要约束基本一致,区别仅在于提供的不是一个引用类型而是一个或多个接口。
注意
同时拥有主要约束和次要约束的泛型参数,表示实参必须同时满足主要约束和次要约束。
答案
每个泛型参数可以有至多一个主要约束,泛型的主要约束是指泛型参数必须是或者继承自某个引用类型,有两个特殊的主要约束:class和struct,分别代表泛型参数是引用类型和值类型。
每个泛型参数可以有无限个次要约束,次要约束和主要约束的语法基本相同,但它规定的是某个泛型参数必须实现所有次要约束指定的接口。