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