简体   繁体   English

我可以使用强类型反射找到具有通用参数的方法吗?

[英]Can I find a method with generic parameters using strongly typed reflection?

Here's my attempt at calling an existing generic method with a type argument. 这是我尝试使用类型参数调用现有泛型方法的尝试。 ' Strongly typed reflection ' may not be a suitable term, but it basically means finding and invoking the reflected method without using a name string. 强类型反射 ”可能不是一个合适的术语,但它基本上意味着在不使用名称字符串的情况下查找和调用反射方法。

public class TestClass
{
    public static void Test(Type type)
    {
        InvokeTestMethodWithType(type);
    }

    private void Test<T>() { ... }

    private static void InvokeTestMethodWithType(Type type)
    {
        // This doesn't compile! - can I find Test<> using this approach?
        Expression<Func<TestClass, Action>> ex = x => x.Test<>;

        // invoke it
        ((MethodCallExpression)ex.Body).Method.MakeGenericMethod(type).Invoke(new TestClass(), null);
    }
}

Sample call would end up call the private Test(). 示例调用最终将调用私有Test()。

TestClass.Test(typeof(Foo))

As you can see, I'm struggling with the expression and not entirely sure if it can be executed in this manner. 如您所见,我正在为该表达式而苦苦挣扎,并不完全确定它是否可以这种方式执行。

Do I have to dummy invoke the action in the expression like this post ? 我是否必须像这篇文章一样虚拟调用表达式中的动作?

x => x.Test<object>()

The trick I use is simple: pass a fake generic type argument: 我使用的技巧很简单:传递一个假的泛型类型参数:

Expression<Func<TestClass, WhateverTestReturns>> ex = x => x.Test<string>();

// invoke it
((MethodCallExpression)ex.Body)
  .Method
  .GetGenericMethodDefinition()
  .MakeGenericMethod(type)
  .Invoke(new TestClass(), null);

The method call expression will then contain a method info for Test<string>() , but you can easily use GetGenericMethodDefinition to remove the generic argument, and then MakeGenericMethod to put a different one back in its place. 然后,方法调用表达式将包含Test<string>()的方法信息,但是您可以轻松地使用GetGenericMethodDefinition删除泛型参数,然后使用MakeGenericMethod将其他参数放回原处。

You don't even need to use Expression in a case like this - simply cast TestClass.Test<string> to a delegate, and you'll have a Method property that gives you the same method info. 在这种情况下,您甚至不需要使用Expression只需将TestClass.Test<string>转换为委托,即可获得为您提供相同方法信息的Method属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM