当参数是通用的时,Type.GetMethod的Type数组中应该包含哪些类型?

如果我想通过reflection调用generics方法,我可以很容易地使用这种技术,除非:

  1. 该方法只能通过其参数区分。
  2. 该方法有一个参数,其类型是方法的类型参数之一。

调用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 Method (IQueryable, Expression>)方法时,我会给你完整的“东西”……这是相当的复杂并检查几乎所有:

 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); 

根据您拥有的方法重载次数,您可能必须使谓词更具体。