泛型及约束
程序中经常会用到泛型,如:
class Program
{
static void Main(string[] args)
{
string a = "a";
string b = "b";
Console.WriteLine("before change, a={0},b={1}.", a, b);
Change<string>(ref a, ref b);
Console.WriteLine("after change, a={0},b={1}.", a, b);
Console.ReadKey();
}
static void Change<T>(ref T a, ref T b)
{
var c = a;
a = b;
b = c;
}
}
但有时候会碰到类似下面的写法,带where的:
static void Change2<T>(ref T a, ref T b) where T:struct
{
var c = a;
a = b;
b = c;
}
刚开始看到未免会比较晕,在msdn上搜索下,原来是泛型约束,详细的泛型约束如下:
约束 | 说明 |
T:Struct | 类型参数必须是值类型。 可以指定除 Nullable 以外的任何值类型。 |
T:Class | 类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。 |
T:New() | 类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new() 约束必须最后指定。 |
T:<BaseClass> | 类型参数必须是指定的基类或派生自指定的基类。 |
T:<Interface> | 类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。 |
T:U | 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。 |
所以,在如果要调用前面加了约束的函数Change2,则必须使用非Nullable类型,如int,不能使用string了。
int a = 1;
int b = 2;
Console.WriteLine("before change, a={0},b={1}.", a, b);
Change2<int>(ref a, ref b);
Console.WriteLine("after change, a={0},b={1}.", a, b);