如何在非泛型.NET类型上获取泛型方法的MethodInfo?

时间:2009-10-26 13:33:34

标签: .net reflection methodinfo generic-method

我有这个小问题,我无法弄清楚要传递给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)

2 个答案:

答案 0 :(得分:7)

问题是您传递给IEnumerable<>的{​​{1}}参数不是专门的。它实际上是GetMethod,其中IEnumerable<T>由您尝试检索的方法指定。但是,我们无法通过T获取T,因为我们没有对该方法的引用 - 我们仍在尝试检索它。

不幸的是,这是反射API不足的地方。没有MethodInfo.GetGenericArguments()重载允许您区分重载方法,其中一个是泛型​​方法。

所以说,你使用Type.GetMethod()并使用你选择的谓词过滤结果。要获得您感兴趣的方法,您可以执行以下操作。

Type.GetMethods()

N.B。我还没有确认需要void getMethod() { typeof(A).GetMethods().Where(m => m.IsGenericMethod && m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable<>)); } 来电;你可以省略它。您的想法是将类型GetGenericTypeDefinition()转换为A<T>,但运行时可能已经以该形式将其提供给您。

答案 1 :(得分: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. 获取通用methodinfo