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

时间:2015-06-27 07:40:18

标签: c# generics reflection

如果我想通过反射调用泛型方法,我可以轻松使用this技术,除非:

  1. 该方法只能通过参数与其他方法区分开来。
  2. 该方法有一个参数,其类型是方法的类型参数之一。
  3. 如何在调用Type[]时在Type.GetMethod(string, Type[])数组中指定通用参数?

    示例:

    public class Example
    {
        //This is the one I want to call.
        public void DoSomething<T>(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);
        }
    

2 个答案:

答案 0 :(得分:1)

你可以这样做:

overlapPlot()

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

答案 1 :(得分:1)

当我必须找到一个Queryable.Select<TSource, TResult> Method (IQueryable<TSource>, Expression<Func<TSource, TResult>>)方法时,我会给你完整的“东西”...它非常复杂并几乎检查所有:

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

您可以轻松地将其用作模板。

请注意,不检查返回类型,因为返回类型没有重载。 static检查方法为publicGetMethods()的事实。我检查参数的数量,通用参数的数量,参数的类型。然后我使用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();