代码之家  ›  专栏  ›  技术社区  ›  dkackman Srinivas Kokkula

如何使用反射找到特定的通用重载?

  •  4
  • dkackman Srinivas Kokkula  · 技术社区  · 16 年前

    Expression Enumerable.Average Reflection 找到并创建正确的泛型方法(

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

    Func<TSource, int> argType == typeof(int) .

    4 回复  |  直到 16 年前
        1
  •  6
  •   Thomas Levesque    16 年前

    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();
    }
    
        2
  •  1
  •   tnyfst    16 年前

    var call = Expression.Call(typeof(Enumerable),
                 "Average",
                new Type[] { typeof(MyTSource) },
                enumerableParameter, lambdaParameter
                    );
    
        3
  •  1
  •   Pop Catalin    16 年前

    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();
    }
    
        4
  •  0
  •   dkackman Srinivas Kokkula    16 年前

    感谢@Joren的链接提示。这个例子根据论点计数进行区分,但它让我走上了正确的方向。

    有效的选择是

    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;