문제

나는 만들려고 노력하고있다 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;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top