반사를 사용하여 특정 일반 과부하를 찾는 방법은 무엇입니까?
-
13-09-2019 - |
문제
나는 만들려고 노력하고있다 Expression
특정 일반적인 과부하 메소드를 호출합니다 (Enumerable.Average
첫 번째 테스트 사례에서). 특정 유형 바인딩은 런타임까지 알려져 있지 않으므로 사용해야합니다. Reflection
올바른 일반 방법 ( Expression
구문 분석 텍스트에서 생성되고 있습니다).
따라서 런타임 에이 특정 오버로드를 찾고 싶다는 것을 알고 있다면 다음과 같습니다.
public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
그 특정을 어떻게 해결합니까? MethodInfo
반사 사용?
지금까지 나는 다음과 같은 선택 진술이 있습니다.
MethodInfo GetMethod(Type argType, Type returnType)
{
var methods = from method in typeof(Enumerable).GetMethods(BindingFlags.Public | BindingFlags.Static)
where method.Name == "Average" &&
method.ContainsGenericParameters &&
method.GetParameters().Length == 2 &&
// and some condition where method.GetParameters()[1] is a Func that returns type argType
method.ReturnType == returnType
select method;
Debug.Assert(methods.Count() == 1);
return methods.FirstOrDefault();
}
위는 3 개의 오버로드로 좁아 지지만 나는 반영하고 특정 오버로드를 찾고 싶습니다. Func<TSource, int>
어디 argType == typeof(int)
.
나는 그루터기가 있고 어떤 도움이든 감사합니다.
해결책
사용해야합니다 MethodInfo.MakeGenericMethod
편집 : 알겠습니다. 문제를 오해했습니다 ...이 방법은 원하는대로해야합니다.
MethodInfo GetMethod(Type argType, Type returnType)
{
var enumerableType = typeof(IEnumerable<>).MakeGenericType(new Type[] { argType });
Console.WriteLine(enumerableType);
var methods = from method in typeof(Enumerable).GetMethods(BindingFlags.Public | BindingFlags.Static)
let parameters = method.GetParameters()
let genParams = method.GetGenericArguments()
where method.Name == "Average" &&
method.ContainsGenericParameters &&
parameters.Length == 2 &&
parameters[1].ParameterType.GetGenericTypeDefinition() == typeof(Func<,>) &&
parameters[1].ParameterType.GetGenericArguments()[1] == argType &&
method.ReturnType == returnType
select method;
return methods.FirstOrDefault();
}
다른 팁
직접 실행하는 대신 표현식을 구축하므로 Methodinfo 단계를 건너 뛰고 표현식을 사용하여 MethodCallexpression으로 바로 이동할 수 있습니다.
var call = Expression.Call(typeof(Enumerable),
"Average",
new Type[] { typeof(MyTSource) },
enumerableParameter, lambdaParameter
);
다음은 다음과 같은 방법입니다.
static MethodInfo GetMethod(Type argType, Type returnType)
{
var methods = from m in typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
where m.ContainsGenericParameters
&& m.Name == "Average"
&& m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Func<,>)
&& m.GetParameters()[1].ParameterType.GetGenericArguments()[1] == returnType
select m;
return methods.First();
}
링크 된 힌트에 감사드립니다. 이 예는 인수 수에 따라 구별되지만 올바른 방향으로 나를 얻었습니다.
작동하는 선택은입니다
var methods = from method in typeof(Enumerable).GetMethods(BindingFlags.Public | BindingFlags.Static)
where method.Name == Name &&
method.ContainsGenericParameters &&
method.ReturnType == returnType &&
method.GetParameters().Length == 2 &&
method.GetParameters()[1].ParameterType.GetGenericArguments().Count() == 2 &&
method.GetParameters()[1].ParameterType.GetGenericArguments()[1] == argType
select method;
제휴하지 않습니다 StackOverflow