泛型方法(C# 编程指南)

泛型方法是通过类型参数声明的方法,如下所示:

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# 语言规范

另请参阅