mar*_*ark 7 .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)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我在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)
Run Code Online (Sandbox Code Playgroud)
问题是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<>));
}
Run Code Online (Sandbox Code Playgroud)
注意我还没有确认GetGenericTypeDefinition()是否需要通话; 你可以省略它.您的想法是将类型A<T>转换为A<>,但运行时可能已经以该形式提供给您.
(在回答问题澄清时更新):
没有办法使用GetMethod(例如一行)来获取方法的句柄,因为在我们有方法检查之前,定义方法的通用数据是不可用的.
MethodInfo[] methods = typeof(A).GetMethods(BindingFlags.Static | BindingFlags.Public);
MethodInfo genericMethod = methods.Where(m=>m.IsGenericMethod).First(m=>m.ContainsGenericParameters);
genericMethod = genericMethod.GetGenericMethodDefinition();
Run Code Online (Sandbox Code Playgroud)