MethodInfo.MakeGenericMethod(Type[]) 方法

定义

用类型数组的元素替代当前泛型方法定义的类型参数,并返回表示结果构造方法的 MethodInfo 对象。

C#
public virtual System.Reflection.MethodInfo MakeGenericMethod(params Type[] typeArguments);

参数

typeArguments
Type[]

要替换当前泛型方法定义的类型参数的类型数组。

返回

一个 MethodInfo 对象,表示通过将当前泛型方法定义的类型参数替换为 typeArguments 的元素生成的构造方法。

例外

当前 MethodInfo 不表示一个泛型方法定义。 也就是说,IsGenericMethodDefinition 返回 false

typeArgumentsnull

typeArguments 的任意元素为 null

typeArguments 中的元素数与当前泛型方法定义的类型参数的数目不同。

typeArguments 的元素不满足当前泛型方法定义的相应类型参数所指定的约束。

不支持此方法。

示例

下面的代码示例演示支持检查泛型方法的属性和 MethodInfo 方法。 示例将执行以下操作:

  • 定义具有泛型方法的类。

  • 创建一个 MethodInfo 表示泛型方法的 。

  • 显示泛型方法定义的属性。

  • 将类型参数分配给 的类型参数, MethodInfo并调用生成的构造泛型方法。

  • 显示构造的泛型方法的属性。

  • 从构造的方法检索泛型方法定义,并将其与原始定义进行比较。

C#
using System;
using System.Reflection;

// Define a class with a generic method.
public class Example
{
    public static void Generic<T>(T toDisplay)
    {
        Console.WriteLine("\r\nHere it is: {0}", toDisplay);
    }
}

public class Test
{
    public static void Main()
    {
        Console.WriteLine("\r\n--- Examine a generic method.");

        // Create a Type object representing class Example, and
        // get a MethodInfo representing the generic method.
        //
        Type ex = typeof(Example);
        MethodInfo mi = ex.GetMethod("Generic");

        DisplayGenericMethodInfo(mi);

        // Assign the int type to the type parameter of the Example
        // method.
        //
        MethodInfo miConstructed = mi.MakeGenericMethod(typeof(int));

        DisplayGenericMethodInfo(miConstructed);

        // Invoke the method.
        object[] args = {42};
        miConstructed.Invoke(null, args);

        // Invoke the method normally.
        Example.Generic<int>(42);

        // Get the generic type definition from the closed method,
        // and show it's the same as the original definition.
        //
        MethodInfo miDef = miConstructed.GetGenericMethodDefinition();
        Console.WriteLine("\r\nThe definition is the same: {0}",
            miDef == mi);
    }

    private static void DisplayGenericMethodInfo(MethodInfo mi)
    {
        Console.WriteLine("\r\n{0}", mi);

        Console.WriteLine("\tIs this a generic method definition? {0}",
            mi.IsGenericMethodDefinition);

        Console.WriteLine("\tIs it a generic method? {0}",
            mi.IsGenericMethod);

        Console.WriteLine("\tDoes it have unassigned generic parameters? {0}",
            mi.ContainsGenericParameters);

        // If this is a generic method, display its type arguments.
        //
        if (mi.IsGenericMethod)
        {
            Type[] typeArguments = mi.GetGenericArguments();

            Console.WriteLine("\tList type arguments ({0}):",
                typeArguments.Length);

            foreach (Type tParam in typeArguments)
            {
                // IsGenericParameter is true only for generic type
                // parameters.
                //
                if (tParam.IsGenericParameter)
                {
                    Console.WriteLine("\t\t{0}  parameter position {1}" +
                        "\n\t\t   declaring method: {2}",
                        tParam,
                        tParam.GenericParameterPosition,
                        tParam.DeclaringMethod);
                }
                else
                {
                    Console.WriteLine("\t\t{0}", tParam);
                }
            }
        }
    }
}

/* This example produces the following output:

--- Examine a generic method.

Void Generic[T](T)
        Is this a generic method definition? True
        Is it a generic method? True
        Does it have unassigned generic parameters? True
        List type arguments (1):
                T  parameter position 0
                   declaring method: Void Generic[T](T)

Void Generic[Int32](Int32)
        Is this a generic method definition? False
        Is it a generic method? True
        Does it have unassigned generic parameters? False
        List type arguments (1):
                System.Int32

Here it is: 42

Here it is: 42

The definition is the same: True

 */

注解

方法 MakeGenericMethod 允许编写将特定类型分配给泛型方法定义的类型参数的代码,从而创建表示 MethodInfo 特定构造方法的对象。 ContainsGenericParameters如果此MethodInfo对象的 属性返回 true,则可以使用它调用 方法或创建委托来调用 方法。

使用 MakeGenericMethod 方法构造的方法可以打开,也就是说,其某些类型参数可以是封闭泛型类型的类型参数。 生成动态程序集时,可以使用此类开放式构造方法。 例如,请考虑以下 C#、Visual Basic 和 C++ 代码。

class C
{
    T N<T,U>(T t, U u) {...}
    public V M<V>(V v)
    {
        return N<V,int>(v, 42);
    }
}

Class C
    Public Function N(Of T,U)(ByVal ta As T, ByVal ua As U) As T
        ...
    End Function
    Public Function M(Of V)(ByVal va As V ) As V
        Return N(Of V, Integer)(va, 42)
    End Function
End Class

ref class C
{
private:
    generic <typename T, typename U> T N(T t, U u) {...}
public:
    generic <typename V> V M(V v)
    {
        return N<V, int>(v, 42);
    }
};

的方法主体 M 包含对 方法 N的调用,指定 的 M 类型参数和类型 Int32。 属性IsGenericMethodDefinition为 方法 N<V,int>返回 false 。 属性 ContainsGenericParameters 返回 true,因此无法调用 方法 N<V,int>

有关特定于泛型方法的术语的固定条件列表,请参阅 IsGenericMethod 属性。 有关泛型反射中使用的其他术语的固定条件列表,请参阅 IsGenericType 属性。

适用于

产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

另请参阅