选择右泛型方法与思考 [英] Select Right Generic Method with Reflection

查看:96
本文介绍了选择右泛型方法与思考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要选择通过反射正确的泛型方法,然后调用它。

I want to select the right generic method via reflection and then call it.

通常这是很容易的。例如:

Usually this is quite easy. For example

var method = typeof(MyType).GetMethod("TheMethod");
var typedMethod = method.MakeGenericMethod(theTypeToInstantiate);

然而问题开始时,有该方法的不同属重载。例如静电方法在System.Linq.Queryable级。还有'Where'法的两个定义

However the issue start when there are different generic overloads of the method. For example the static-methods in the System.Linq.Queryable-class. There are two definitions of the 'Where'-method

static IQueryable<T> Where(this IQueryable<T> source, Expression<Func<T,bool>> predicate)
static IQueryable<T> Where(this IQueryable<T> source, Expression<Func<T,int,bool>> predicate)

这是劲歌GetMethod不起作用,因为它不能destiguish两个。因此,我想选择是正确的。

This meand that GetMethod doesn't work, because it cannot destiguish the two. Therefore I want to select the right one.

到目前为止,我往往只是采取了第一个或第二个方法,根据我的需要。像这样的:

So far I often just took the first or second method, depending on my need. Like this:

var method = typeof (Queryable).GetMethods().First(m => m.Name == "Where");
var typedMethod = method.MakeGenericMethod(theTypeToInstantiate);

不过,我不是很满意这一点,因为我使一个巨大的假设,第一种方法是正确的。我宁愿要找到参数类型正确的方法。但我无法弄清楚如何。

However I'm not happy with this, because I make a huge assumption that the first method is the right one. I rather want to find the right method by the argument type. But I couldn't figure out how.

我传递类型尝试过,但没有奏效。

I tried it with passing the 'types', but it didn't work.

        var method = typeof (Queryable).GetMethod(
            "Where", BindingFlags.Static,
            null,
            new Type[] {typeof (IQueryable<T>), typeof (Expression<Func<T, bool>>)},
            null);

所以,有没有人一个想法,我怎么能找到通过反射正确的泛型方法。例如在可查询类的Where'法的正确版本?

So has anyone an idea how I can find the 'right' generic method via reflection. For example the right version of the 'Where'-method on the Queryable-class?

推荐答案

这是可以做到的,但它不是pretty!

It can be done, but it's not pretty!

例如,要获得的第一个重载其中,在你的问题,你可以做到这一点提到:

For example, to get the first overload of Where mentioned in your question you could do this:

var where1 = typeof(Queryable).GetMethods()
                 .Where(x => x.Name == "Where")
                 .Select(x => new { M = x, P = x.GetParameters() })
                 .Where(x => x.P.Length == 2
                             && x.P[0].ParameterType.IsGenericType
                             && x.P[0].ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>)
                             && x.P[1].ParameterType.IsGenericType
                             && x.P[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>))
                 .Select(x => new { x.M, A = x.P[1].ParameterType.GetGenericArguments() })
                 .Where(x => x.A[0].IsGenericType
                             && x.A[0].GetGenericTypeDefinition() == typeof(Func<,>))
                 .Select(x => new { x.M, A = x.A[0].GetGenericArguments() })
                 .Where(x => x.A[0].IsGenericParameter
                             && x.A[1] == typeof(bool))
                 .Select(x => x.M)
                 .SingleOrDefault();

或者,如果你想第二个过载:

Or if you wanted the second overload:

var where2 = typeof(Queryable).GetMethods()
                 .Where(x => x.Name == "Where")
                 .Select(x => new { M = x, P = x.GetParameters() })
                 .Where(x => x.P.Length == 2
                             && x.P[0].ParameterType.IsGenericType
                             && x.P[0].ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>)
                             && x.P[1].ParameterType.IsGenericType
                             && x.P[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>))
                 .Select(x => new { x.M, A = x.P[1].ParameterType.GetGenericArguments() })
                 .Where(x => x.A[0].IsGenericType
                             && x.A[0].GetGenericTypeDefinition() == typeof(Func<,,>))
                 .Select(x => new { x.M, A = x.A[0].GetGenericArguments() })
                 .Where(x => x.A[0].IsGenericParameter
                             && x.A[1] == typeof(int)
                             && x.A[2] == typeof(bool))
                 .Select(x => x.M)
                 .SingleOrDefault();

这篇关于选择右泛型方法与思考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆