开发者

How can I get the MethodInfo of Queryable.Join

开发者 https://www.devze.com 2023-04-12 21:24 出处:网络
This may sound stupid but I cannot get the MethodInfo of Queryable.Join(...). I want to get it because of How to use a Type variable in a generic method call (C#)

This may sound stupid but I cannot get the MethodInfo of Queryable.Join(...). I want to get it because of How to use a Type variable in a generic method call (C#)

It has 2 available method signatures and I want to get the one without IEqualityComparer, so I need to specify Type[] in GetMethod.

I wrote something like

MethodInfo joinMethod = typeof( Queryable ).GetMethod( "Join", new Type[] { typeof(IEnumerable<>), typeof(Expression<Func<>>), typeof(Expression<Func<开发者_C百科;>>), typeof(Expression<Func<>>)});

but it doesn't work. I'm unable to specify the types in generics above, because they are passed as Type from outside (and this is why I need this reflection).

Can anyone tell me how? Thanks!


Working with generics and reflection can be a bit tedious. Your best bet (to keep things simple) is to use GetMethods and filter by what you are looking for.

//Overly simplified
MethodInfo joinMethod = typeof(Queryable)
            .GetMethods(BindingFlags.Static | BindingFlags.Public)
            .Where(m => m.Name == "Join" && m.GetParameters().Length == 5)
            .First();

Given that, the MethodInfo is not invokable at this point. You need to make a generic version of it by using joinMethod.MakeGenericMethod(/*type array*/). In your case, you would need to use 4 types: TOuter, TInner, TKey, TResult.

var genericJoinMethod = joinMethod.MakeGenericMethod(new Type[]{your types here});

Now you can use genericJoinMethod as you'd expect to.

As far as I know, that is the only way to do it if you don't know the types at compile-time.

EDIT:

Given your comment, I think it should look something like this:

MethodInfo joinMethod = typeof(Queryable)
            .GetMethods(BindingFlags.Static | BindingFlags.Public)
            .Where(m => m.Name == "Join" && m.GetParameters().Length == 5)
            .First();
var genericJoinMethod = joinMethod.MakeGenericMethod(typeof(TType), typeof(TType), JoinKeyType, typeof(TType));
result = genericJoinMethod.Invoke( result, new object[] { result, items, OuterKeySelector, InnerKeySelector, ResultSelector } );


Before you start to implement some complicated reflection search with strings and parameter counts involved, why don't you step back, and let the compiler do what he is better at?

var fakeExp = (Expression<Func<IQueryable<int>>>)(() => new int[0].AsQueryable().Join(new int[0], x => x, x => x, (x, y) => x));
return ((MethodCallExpression)fakeExp.Body).Method.GetGenericMethodDefinition();

Obviously you can put whatever you want in your expression, as long as the top level stuff is your Join method call. Types do not matter neither.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号