泛型方法(C# 编程指南)Generic Methods (C# Programming Guide)

泛型方法是通过类型参数声明的方法,如下所示:A generic method is a method that is declared with type parameters, as follows:

static void Swap<T>(ref T lhs, ref T rhs)
{
    T temp;
    temp = lhs;
    lhs = rhs;
    rhs = temp;
}

如下示例演示使用类型参数的 int 调用方法的一种方式:The following code example shows one way to call the method by using int for the type argument:

public static void TestSwap()
{
    int a = 1;
    int b = 2;

    Swap<int>(ref a, ref b);
    System.Console.WriteLine(a + " " + b);
}

还可省略类型参数,编译器将推断类型参数。You can also omit the type argument and the compiler will infer it. 如下 Swap 调用等效于之前的调用:The following call to Swap is equivalent to the previous call:

Swap(ref a, ref b);

类型推理的相同规则适用于静态方法和实例方法。The same rules for type inference apply to static methods and instance methods. 编译器可基于传入的方法参数推断类型参数;而无法仅根据约束或返回值推断类型参数。The compiler can infer the type parameters based on the method arguments you pass in; it cannot infer the type parameters only from a constraint or return value. 因此,类型推理不适用于不具有参数的方法。Therefore type inference does not work with methods that have no parameters. 类型推理发生在编译时,之后编译器尝试解析重载的方法签名。Type inference occurs at compile time before the compiler tries to resolve overloaded method signatures. 编译器将类型推理逻辑应用于共用同一名称的所有泛型方法。The compiler applies type inference logic to all generic methods that share the same name. 在重载解决方案步骤中,编译器仅包含在其上类型推理成功的泛型方法。In the overload resolution step, the compiler includes only those generic methods on which type inference succeeded.

在泛型类中,非泛型方法可访问类级别类型参数,如下所示:Within a generic class, non-generic methods can access the class-level type parameters, as follows:

class SampleClass<T>
{
    void Swap(ref T lhs, ref T rhs) { }
}

如果定义一个具有与包含类相同的类型参数的泛型方法,则编译器会生成警告 CS0693,因为在该方法范围内,向内 T 提供的参数会隐藏向外 T 提供的参数。If you define a generic method that takes the same type parameters as the containing class, the compiler generates warning CS0693 because within the method scope, the argument supplied for the inner T hides the argument supplied for the outer T. 如果需要使用类型参数(而不是类实例化时提供的参数)调用泛型类方法所具备的灵活性,请考虑为此方法的类型参数提供另一标识符,如下方示例中 GenericList2<T> 所示。If you require the flexibility of calling a generic class method with type arguments other than the ones provided when the class was instantiated, consider providing another identifier for the type parameter of the method, as shown in GenericList2<T> in the following example.

class GenericList<T>
{
    // CS0693
    void SampleMethod<T>() { }
}

class GenericList2<T>
{
    //No warning
    void SampleMethod<U>() { }
}

使用约束在方法中的类型参数上实现更多专用操作。Use constraints to enable more specialized operations on type parameters in methods. 此版 Swap<T> 现名为 SwapIfGreater<T>,仅可用于实现 IComparable<T> 的类型参数。This version of Swap<T>, now named SwapIfGreater<T>, can only be used with type arguments that implement 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;
    }
}

泛型方法可重载在数个泛型参数上。Generic methods can be overloaded on several type parameters. 例如,以下方法可全部位于同一类中:For example, the following methods can all be located in the same class:

void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }

C# 语言规范C# Language Specification

有关详细信息,请参阅 C# 语言规范For more information, see the C# Language Specification.

请参阅See also