泛型方法是声名了类型参数的方法,如下:
void Swap<T>( ref T lhs, ref T rhs) { T temp; temp = lhs; lhs = rhs; rhs = temp; }
下面的示例代码显示了一个以int作为类型参数,来调用方法的例子:
int a = 1; int b = 2; //… Swap<int>(a, b);
也可以忽略类型参数,编译器会去推断它。下面调用Swap的代码与上面的例子等价:
Swap(a, b);
静态方法和实例方法有着同样的类型推断规则。编译器能够根据传入的方法参数来推断类型参数;而无法单独根据约束或返回值来判断。因此类型推断对没有参数的方法是无效的。类型推断发生在编译的时候,且在编译器解析重载方法标志之前。编译器对所有同名的泛型方法应用类型推断逻辑。在决定(resolution)重载的阶段,编译器只包含那些类型推断成功的泛型类。更多信息,请参见C# 2.0规范,20.6.4类型参数推断
在泛型方法中,非泛型方法能访问所在类中的类型参数,如下:
class MyClass<T> { //… void Swap (ref T lhs, ref T rhs){…} }
[JX1] 定义一个泛型方法,和其所在的类具有相同的类型参数;试图这样做,编译器会产生警告CS0693。
class MyList<T> { // CS0693 void MyMethod<T>{...} } class MyList<T> { //This is okay, but not common. void SomeMethod<U>(){...} }
使用约束可以在方法中使用更多的类型参数的特定方法。这个版本的Swap<T>称为SwapIfGreater<T>,它只能使用实现了IComparable<T>的类型参数。
void SwapIfGreater<T>( ref T lhs, ref T rhs) where T: IComparable<T> { T temp; if(lhs.CompareTo(rhs) > 0) { temp = lhs; lhs = rhs; rhs = temp; } }
泛型方法通过多个类型参数来重载。例如,下面的这些方法可以放在同一个类中:
void DoSomething(){} void DoSomething<T>(){} void DoSomething<T,U>(){}