8

我有这个小问题,我无法弄清楚要传递给 Type.GetMethod 的参数,以便在非泛型类型上取回泛型方法的 MethodInfo。具体来说,我有这个类型定义:

public static class A
{
  public static B F<T>(bool dummy)
  {
  }
  public static B F<T>(IEnumerable<T> arg)
  {
  ...
  }
}

我在 Type.GetMethod 上尝试了几次,但没有一个会返回 F 方法的 MethodInfo。

我知道我可以调用 Type.GetMethods 甚至 Type.FindMember,但我对 Type.GetMethod 很感兴趣。

有任何想法吗?

谢谢。

编辑

实际上,我的代码有点复杂。泛型方法被重载,所以我不能只使用函数名来使用 Type.GetMethod。我尝试了这些变体:

typeof(A).GetMethod("F", BindingFlags.Static | BindingFlags.Public, null, new Type[]{ typeof(IEnumerable<>) }, null)
typeof(A).GetMethod("F`1", BindingFlags.Static | BindingFlags.Public, null, new Type[]{ typeof(IEnumerable<>) }, null)
typeof(A).GetMethod("F[T]", BindingFlags.Static | BindingFlags.Public, null, new Type[]{ typeof(IEnumerable<>) }, null)
typeof(A).GetMethod("F[[T]]", BindingFlags.Static | BindingFlags.Public, null, new Type[]{ typeof(IEnumerable<>) }, null)
4

2 回答 2

9

问题是IEnumerable<>您传递给的参数GetMethod不是专门的。它确实是一个IEnumerable<T>,T由您尝试检索的方法指定。但是,我们无法T通过,MethodInfo.GetGenericArguments()因为我们没有对该方法的引用——我们仍在尝试检索它。

不幸的是,这就是反射 API 的不足之处。没有Type.GetMethod()重载可以让您区分重载方法,其中一个是泛型​​方法。

因此,话虽如此,您仍然无法使用Type.GetMethods()您选择的谓词来使用和过滤结果。要获得您感兴趣的方法,您可以执行以下操作。

void getMethod()
{
    typeof(A).GetMethods().Where(m =>
        m.IsGenericMethod &&
        m.GetParameters()[0].ParameterType.GetGenericTypeDefinition()
            == typeof(IEnumerable<>));
}

注意我还没有验证GetGenericTypeDefinition()是否需要调用;你可以省略它。这个想法是您正在将类型A<T>转换为A<>,但运行时可能已经以这种形式将其提供给您。

于 2009-10-26T14:19:50.193 回答
5

(根据问题说明进行了更新):

无法使用GetMethod(例如,一行)获取方法的句柄,因为在我们有要检查的方法之前,定义该方法的通用数据不可用。

MethodInfo[] methods = typeof(A).GetMethods(BindingFlags.Static | BindingFlags.Public);
MethodInfo genericMethod = methods.Where(m=>m.IsGenericMethod).First(m=>m.ContainsGenericParameters);
genericMethod = genericMethod.GetGenericMethodDefinition();
  1. 获取方法
  2. 找到具有通用参数的方法(假设您只有一个 - 如果添加多个,则需要更健壮一些)
  3. 获取通用方法信息
于 2009-10-26T13:36:52.447 回答