如何使用给定的Type对象调用泛型方法?

时间:2009-09-10 22:47:26

标签: c# .net generics reflection types

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

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

显然不起作用。

我怎样才能让它发挥作用?

3 个答案:

答案 0 :(得分:56)

您的代码示例将不起作用,因为泛型方法需要类型标识符,而不是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);
    }
}

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

另一个hacky解决方案(也许有人可以让它更清洁一点)就是使用一些表达魔术:

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);
    }
}

注意将'object'类型标识符作为lambda中的泛型类型参数传递。无法弄清楚如何快速解决这个问题。无论哪种方式,我认为这是编译时安全的。以某种方式感觉不对:/

答案 1 :(得分:17)

不幸的是,您需要使用反射(出于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 });

但似乎 是现实中的参数数组,online MSDN docs同意。奇

答案 2 :(得分:-2)

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