Как я могу получить MethodInfo из Queryable.Join - PullRequest
2 голосов
/ 14 октября 2011

Это может звучать глупо, но я не могу получить MethodInfo из Queryable.Join(...).Я хочу получить его из-за Как использовать переменную Type в общем вызове метода (C #)

У него есть 2 доступные сигнатуры методов, и я хочу получить одну без IEqualityComparer, поэтомуМне нужно указать Type[] в GetMethod.

Я написал что-то вроде

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

, но это не работает.Я не могу указать типы в обобщенных выше, потому что они передаются как Type извне (и именно поэтому мне нужно это отражение).

Может кто-нибудь сказать мне, как?Спасибо!

Ответы [ 2 ]

5 голосов
/ 14 октября 2011

Работа с обобщениями и рефлексией может быть немного утомительной. Лучше всего (для простоты) использовать GetMethods и фильтровать по тому, что вы ищете.

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

Учитывая, что MethodInfo не вызывается в этот момент. Вам нужно сделать его общую версию, используя joinMethod.MakeGenericMethod(/*type array*/). В вашем случае вам нужно будет использовать 4 типа: TOuter, TInner, TKey, TResult.

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

Теперь вы можете использовать genericJoinMethod так, как вы ожидаете.

Насколько я знаю, это единственный способ сделать это, если вы не знаете типы во время компиляции.

EDIT

Учитывая ваш комментарий, я думаю, это должно выглядеть примерно так:

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 } );
1 голос
/ 04 июня 2014

Прежде чем вы начнете реализовывать сложный поиск отражений с учетом количества строк и параметров, почему бы вам не сделать шаг назад и позволить компилятору делать то, что у него лучше?

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

Очевидно, что вы можете поместить в выражение все, что захотите, при условии, что на верхнем уровне находится вызов метода Join. Типы не имеют значения ни.

...