我有这种类型,包含泛型方法的两个重载。我喜欢使用反射检索其中一个重载(使用Func<T>
参数)。但问题是我无法找到正确的参数类型来为Type.GetMethod(string, Type[])
方法提供。
这是我的班级定义:
public class Foo
{
public void Bar<T>(Func<T> f) { }
public void Bar<T>(Action<T> a) { }
}
这就是我想出来的,遗憾的是没有成功:
[TestMethod]
public void Test1()
{
Type parameterType = typeof(Func<>);
var method = typeof(Foo).GetMethod("Bar", new Type[] { parameterType });
Assert.IsNotNull(method); // Fails
}
如何获得我知道参数的通用方法的MethodInfo
?
答案 0 :(得分:9)
答案 1 :(得分:4)
令人惊讶的是,看起来您需要调用GetMethods()
并循环使用这些方法,直到找到所需的方法。
例如:
var yourMethod = typeof(Foo).GetMethods()
.First(m => m.Name == "Bar"
&& m.GetParameters().Length == 1
&& m.GetParameters()[0].ParameterType.ContainsGenericParameters
&& m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(Func<>));
答案 2 :(得分:1)
您需要使用MethodInfo.MakeGenericMethod.
但是,我应该指出,当你有一个重载的泛型方法时,获取正确的类型来调用MakeGenericMethod
并不容易。
以下是一个例子:
var method = typeof(Foo)
.GetMethods()
.Where(x => x.Name == "Bar")
.Where(x => x.IsGenericMethod)
.Where(x => x.GetGenericArguments().Length == 1)
.Where(x => x.GetParameters().Length == 1)
.Where(x =>
x.GetParameters()[0].ParameterType ==
typeof(Action<>).MakeGenericType(x.GetGenericArguments()[0])
)
.Single();
method = method.MakeGenericMethod(new Type[] { typeof(int) });
Foo foo = new Foo();
method.Invoke(foo, new Func<int>[] { () => return 42; });
答案 3 :(得分:1)
我不想你可以使用GetMethod
直接做到这一点。我怀疑你必须迭代所有名为Bar
的方法,然后:
Func<T>
(typeof(Func<>).MakeGenericType
),并检查参数类型是否匹配。LINQ对这类事情有好处。完整样本:
using System;
using System.Reflection;
using System.Linq;
public class Foo
{
public void Bar<T>(Func<T> f) { }
public void Bar<T>(Action<T> a) { }
}
class Test
{
static void Main()
{
var methods = from method in typeof(Foo).GetMethods()
where method.Name == "Bar"
let typeArgs = method.GetGenericArguments()
where typeArgs.Length == 1
let parameters = method.GetParameters()
where parameters.Length == 1
where parameters[0].ParameterType ==
typeof(Func<>).MakeGenericType(typeArgs[0])
select method;
Console.WriteLine("Matching methods...");
foreach (var method in methods)
{
Console.WriteLine(method);
}
}
}
基本上,仿制药和反思在组合中真的很讨厌,我担心:(
答案 4 :(得分:0)
你只需要使用GetMethod就可以解决问题 - 你可以尝试一些方法;
var method = (from m in typeof(Foo).GetMethods()
where
m.IsGenericMethodDefinition == true &&
m.Name == "Bar" &&
m.GetParameters().Length > 0 &&
m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == parameterType
select m).FirstOrDefault();