泛型方法是使用类型参数声明的方法,如下所示:
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
下面的代码示例演示了一种通过使用 int
类型参数调用方法的方法:
public static void TestSwap()
{
int a = 1;
int b = 2;
Swap<int>(ref a, ref b);
System.Console.WriteLine(a + " " + b);
}
还可以省略类型参数,编译器将推断它。 以下调用 Swap
等效于上一次调用:
Swap(ref a, ref b);
类型推理的相同规则适用于静态方法和实例方法。 编译器可以根据传入的方法参数推断类型参数;它不能仅从约束或返回值推断类型参数。 因此,类型推理不适用于没有参数的方法。 在编译器尝试解析重载的方法签名之前,在编译时发生类型推理。 编译器将类型推理逻辑应用于共享同名的所有泛型方法。 在重载解析步骤中,编译器仅包含那些类型推理成功的泛型方法。
在泛型类中,非泛型方法可以访问类级类型参数,如下所示:
class SampleClass<T>
{
void Swap(ref T lhs, ref T rhs) { }
}
如果定义采用与包含类相同的类型参数的泛型方法,编译器会生成警告 CS0693 ,因为在方法范围内,为内部 T
提供的参数会隐藏为外部 T
提供的参数。 如果需要使用类型参数(而不是类实例化时提供的参数)调用泛型类方法所具备的灵活性,请考虑为此方法的类型参数提供另一标识符,如下方示例中 GenericList2<T>
所示。
class GenericList<T>
{
// CS0693.
void SampleMethod<T>() { }
}
class GenericList2<T>
{
// No warning.
void SampleMethod<U>() { }
}
在方法中使用对类型参数的约束来允许更专业化的操作。 此版本的 Swap<T>
现已命名 SwapIfGreater<T>
,只能与实现 IComparable<T>的类型参数一起使用。
void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
T temp;
if (lhs.CompareTo(rhs) > 0)
{
temp = lhs;
lhs = rhs;
rhs = temp;
}
}
可以在多个类型参数上重载泛型方法。 例如,以下方法都可以位于同一类中:
void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }
还可以使用类型参数作为方法的返回类型。 下面的代码示例演示返回类型 T
数组的方法:
T[] Swap<T>(T a, T b)
{
return [b, a];
}
C# 语言规范
有关详细信息,请参阅 C# 语言规范。