CodeGo.net>如何使用给定的类型对象调用泛型方法?

这个问题已经在这里有了答案:

  • 如何使用反射调用泛型方法?                                     7个答案

我想用给定的类型对象调用我的通用方法。

void Foo(Type t)
{
     MyGenericMethod<t>();
}

显然是行不通的。

我该如何运作?

codymanix asked 2020-01-13T10:10:16Z
3个解决方案
56 votes

您的代码示例将不起作用,因为通用方法需要类型标识符,而不是Type类的实例。 您必须使用反射来做到这一点:

public class Example {

    public void CallingTest()
    {
        MethodInfo method = typeof (Example).GetMethod("Test");
        MethodInfo genericMethod = method.MakeGenericMethod(typeof (string));
        genericMethod.Invoke(this, null);

    }

    public void Test<T>()
    {
        Console.WriteLine(typeof (T).Name);
    }
}

请记住,这非常脆弱,我宁愿建议您找到另一种模式来调用您的方法。

另一个骇人听闻的解决方案(也许有人可以使其变得更干净)将是使用一些表达魔术:

public class Example {

    public void CallingTest()
    {
        MethodInfo method = GetMethod<Example>(x => x.Test<object>());
        MethodInfo genericMethod = method.MakeGenericMethod(typeof (string));
        genericMethod.Invoke(this, null);

    }

    public static MethodInfo GetMethod<T>(Expression<Action<T>> expr)
    {
        return ((MethodCallExpression) expr.Body)
            .Method
            .GetGenericMethodDefinition();
    }

    public void Test<T>()
    {
        Console.WriteLine(typeof (T).Name);
    }
}

请注意,在lambda中将“对象”类型标识符作为通用类型参数传递。 无法如此迅速地找到解决方法。 无论哪种方式,我认为这都是编译时安全的。 只是感觉不对:/

Erik van Brakel answered 2020-01-13T10:10:53Z
18 votes

不幸的是,您需要使用反射(出于Jared提到的原因)。 例如:

MethodInfo method = typeof(Foo).GetMethod("MyGenericMethod");
method = method.MakeGenericMethod(t);
method.Invoke(this, new object[0]);

显然,您实际上希望进行更多的错误检查:)


旁注:我的本地MSDN未指定MakeGenericMethod中的参数为参数数组,因此,我期望有以下要求:

method = method.MakeGenericMethod(new Type[] { t });

但实际上它似乎是一个参数数组,在线MSDN文档也同意。 奇。

Jon Skeet answered 2020-01-13T10:11:26Z
-2 votes

这种方法行不通。 原因是Type是在运行时确定类型的对象。 但是,您试图使用它来调用通用方法。 泛型方法调用的类型在编译时建立。 因此,类型对象永远不能用作泛型方法上的类型参数。

JaredPar answered 2020-01-13T10:11:47Z
translate from https://stackoverflow.com:/questions/1408120/how-to-call-generic-method-with-a-given-type-object