如何参考方法?

时间:2010-12-30 01:09:13

标签: c# reflection

我正在尝试为Web应用程序创建路由器(是的,我知道解决方案已经存在)。

到目前为止,我已经得到了这个:

class Route
{
    public static RegexOptions DefaultOptions = RegexOptions.IgnoreCase;

    Regex regex;
    Type controller;
    MethodInfo action;

    public Route(string pattern, Type controller)
    {
        this.regex = new Regex(string.Format("^(?:{0})$", pattern), DefaultOptions);
        this.controller = controller;
    }
}

而且:

    Route[] routes = {
        new Route(@"/user:(?<id>\d+)", typeof(UserController))
    };

当网址与该正则表达式匹配时,它应该调用类action中的方法controller。我在想typeof()是我可以通过课程的唯一方法,但该方法怎么样?

我认为MethodInfo是我想要的对象,因为我应该可以调用它,但从API的角度来看,Route构造函数的第三个参数应该是什么,以及应该如何我们称之为?

我更喜欢强类型解决方案,而不是一些字符串恶作剧。

3 个答案:

答案 0 :(得分:3)

我认为没有实例可以在c sharp中引用实例方法。除非您希望API的用户定义要传入的MethodInfo对象,否则字符串名称可能是最佳方式。

static class Program
{
    static void Main()
    {
        Route r = new Route("pattern", typeof(UserController), "Action");
    }
}

public class Route
{
    public Route(string pattern, Type type, string methodName)
    {
        object objectToUse = Activator.CreateInstance(type, null);
        MethodInfo method = type.GetMethod(methodName);
        string[] args = new string[1];
        args[0] = "hello world";
        method.Invoke(objectToUse, args);
    }
}

public class UserController
{
    public void Action(string message)
    {
        MessageBox.Show(message);
    }
}

答案 1 :(得分:1)

您正在寻找不存在的infoof operator

不幸的是,它不存在。

最简单的答案是取一个字符串 或者,您可以选择expression tree 获取表达式树的缺点是调用者必须传递所有参数 您可以将其用于您的框架(通过采用Expression<Func<parameters, ResultType>>),甚至可以编译表达式树来调用操作。 (这将导致比反射更快的调用)

答案 2 :(得分:1)

您可以创建以下内容:

MethodInfo GetMethodInfo(LambdaExpression expression)
{
    var call = expression.Body as MethodCallExpression;
    if(call == null) throw new ArgumentException("Must be a method call","expression");
    return call.Method;
}

MethodInfo GetMethodInfo<T>(Expression<Action<T>> expression)
{
    return GetMethodInfo(expression);
}

MethodInfo GetMethodInfo<T, TResult>(Expression<Func<T, TResult>> expression)
{
    return GetMethodInfo(expression);
}

并像这样使用它:

MethodInfo action = GetMethodInfo((UserController c) => c.ActionMethod());
// or
MethodInfo action = GetMethodInfo((UserController c) =>
                                        c.ActionMethodWithParams(default(int)));

这不会立即调用该方法,因为它是一个表达式树,即表示方法调用的语法树。