当参数是通用的时,Type.GetMethod的Type数组中应该包含哪些类型?
如果我想通过reflection调用generics方法,我可以很容易地使用这种技术,除非:
- 该方法只能通过其参数区分。
- 该方法有一个参数,其类型是方法的类型参数之一。
调用Type.GetMethod(string, Type[])
时,如何在Type[]
数组中指定generics参数?
例:
public class Example { //This is the one I want to call. public void DoSomething(T t) { ... } public void DoSomething(Foo foo) { ... } public void CallDoSomething(Type type, object value) { MethodInfo method = typeof(Example) .GetMethod("DoSomething", new Type[] {/* what do i put here? */ }); MethodInfo generic = method.MakeGenericMethod(type); generic.Invoke(this, value); }
当我必须找到一个Queryable.Select
方法时,我会给你完整的“东西”……这是相当的复杂并检查几乎所有:
MethodInfo selectMethod = (from x in typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public) where x.Name == "Select" && x.IsGenericMethod let pars = x.GetParameters() where pars.Length == 2 let args = x.GetGenericArguments() where args.Length == 2 && pars[0].ParameterType == typeof(IQueryable<>).MakeGenericType(args[0]) && pars[1].ParameterType == typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(args)) select x).Single();
您可以轻松地将其用作模板。
请注意,不检查返回类型,因为返回类型没有重载。 GetMethods()
检查方法是static
还是public
。 我检查参数的数量,通用参数的数量,参数的类型。 然后我使用Single()
来确保只有一个方法。 这应该是面向未来的:即使Microsoft添加了另一个Queryable.Select
方法,它也会“不同”。
在您的具体情况:
MethodInfo method = (from x in typeof(Example).GetMethods(BindingFlags.Instance | BindingFlags.Public) where x.Name == "DoSomething" && x.IsGenericMethod let pars = x.GetParameters() where pars.Length == 1 let args = x.GetGenericArguments() where args.Length == 1 && pars[0].ParameterType == args[0] select x).Single();
你可以这样做:
MethodInfo method = typeof(Example) .GetMethods().First(mi => mi.Name == "DoSomething" && mi.IsGenericMethod);
根据您拥有的方法重载次数,您可能必须使谓词更具体。