我想通过反思得到一个方法

时间:2014-08-26 09:37:59

标签: c# .net reflection

我希望通过反射获得一个方法,但该方法有多个重载...方法的参数是通用类型。我该怎么办?

class Program
{
    static void Main(string[] args)
    {
        test obj = new test();
        Type[] types = { typeof(string) };
        var method = obj.GetType().GetMethod("Say", BindingFlags.Instance | BindingFlags.NonPublic, null, types, null);
        method.Invoke(obj, new object[] { "hello world" });
        Console.ReadKey();
    }
}

public class test
{
    private void Say(string value)
    {
        Console.WriteLine(value);
    }
    private void Say<T>(T t)
    {
        Console.WriteLine(t);
    }
}

我可以private void Say(string value) ..但我想获得private void Say<T>(T t) ..

Type[] types = { typeof(string) };这里如何设置?

2 个答案:

答案 0 :(得分:0)

有你的方法。

获取所有方法并找到您正在寻找的方法

obj.GetType().GetMethods().Single(m=>m.GetParameters().Length = /* parameter count*/ && /* next condition */);

使用表达式树 在我看来,它更好,更不容易出错,但只有在编译时知道你想要哪种方法时才能使用。

您需要一些帮助方法来提取表达式树的方法。

public static MethodInfo Method(Expression<Action> methodAccess)
{
  return ((MethodCallExpression)methodAccess.Body).Method;
}

然后你可以像这样使用它:

Get(()=>obj.Say<string>("My param")).GetGenericMethodDefinition();

编译器将负责选择方法,而helper方法将从表达式树中提取MethodInfo。 GetGenericMethodDefinition()调用将为您提供所选方法的开放式通用版本。

答案 1 :(得分:0)

根据评论,我宁愿选择以下解决方案:

public static MethodInfo GetGenericMethod(object obj, string methodName, Type genericParameter)
{
    var method = obj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault(m => m.Name.Equals(methodName) && m.IsGenericMethod);
    return method.MakeGenericMethod(genericParameter);
}

然后用类似的东西来打电话:

GetGenericMethod(obj, "Say", typeof(string));

然后您就可以像任何其他方法一样调用它。