C# 如何引用方法?

C# 如何引用方法?,c#,reflection,C#,Reflection,我正在尝试为web应用程序创建路由器(是的,我知道解决方案已经存在) 到目前为止,我得到了这个: class Route { public static RegexOptions DefaultOptions = RegexOptions.IgnoreCase; Regex regex; Type controller; MethodInfo action; public Route(string pattern, Type controller)

我正在尝试为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))
    };
Route[]路由={
新路由(@)/用户:(?\d+),类型(用户控制器))
};
当URL与该正则表达式匹配时,它应该调用class
controller
中的方法
action
。我认为
typeof()
是传递类的唯一方法,但是方法呢

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


我更喜欢强类型的解决方案,而不是一些字符串把戏。

您正在寻找不存在的解决方案

不幸的是,它并不存在

最简单的答案是使用字符串。
或者,您也可以采取行动。
采用表达式树的缺点是调用者必须传递所有参数。

您可以将其应用到框架中(通过使用
表达式
),甚至可以编译表达式树来调用操作。(这将导致比反射更快的调用)

您正在寻找不存在的调用

不幸的是,它并不存在

最简单的答案是使用字符串。
或者,您也可以采取行动。
采用表达式树的缺点是调用者必须传递所有参数。

您可以将其应用到框架中(通过使用
表达式
),甚至可以编译表达式树来调用操作。(这将导致比反射更快的调用)

您可以创建如下内容:

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

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

您可以创建如下内容:

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

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

我认为在没有实例的情况下,在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);
    }
}

我认为在没有实例的情况下,没有一种方法可以引用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);
    }
}


动作法应该叫什么?@Martinho:嗯?“行动”很好。我的问题是关于语法的。理想情况下,我只需编写
新路由(“pattern”,UserController.Method)
,但C#不支持这种语法。应该调用什么动作方法?@Martinho:Huh?“行动”很好。我的问题是关于语法的。理想情况下,我只需编写
新路由(“pattern”,UserController.Method)
,但C#不支持这种语法。这假设控制器方法不带参数。否则,必须传递
null
default()!一些人提到了这些“表达式树”,但没有人提供代码示例。。我想我现在明白了。谢谢:)@statenjason:不,它没有假设任何关于控制器操作的内容(有几分钟它假设了一个返回值,但从来没有假设任何关于参数的内容)。但是,是的,您必须传递虚拟值。我更喜欢默认值,因为它有助于在重载之间进行选择。这假设控制器方法不带参数。否则,必须传递
null
default()!一些人提到了这些“表达式树”,但没有人提供代码示例。。我想我现在明白了。谢谢:)@statenjason:不,它没有假设任何关于控制器操作的内容(有几分钟它假设了一个返回值,但从来没有假设任何关于参数的内容)。但是,是的,您必须传递虚拟值。我更喜欢默认值,因为它有助于在重载之间进行选择。。。也许使用字符串毕竟更好更简单,即使我没有获得编译时类型安全性。然而,为了处理歧义,我会让它返回
MethodInfo[]
以及所有可能的匹配:)那篇
infoof
文章提到了一些我没有真正考虑过的问题。。。也许使用字符串毕竟更好更简单,即使我没有获得编译时类型安全性。但是,为了处理歧义,我会让它返回
MethodInfo[]
和所有可能的匹配:)等待…
新回调(动作)
,如果
Action
是UserController中的实例方法。。。这是如何编译的?@Ralph:[Delegates](如
Callback
表示方法,如“可以运行的代码片段”。MethodInfo表示方法,如“具有名称和签名的成员”.我很惊讶没有人这么早说..甚至没有人提到委托!哦..你事先初始化了一个user实例。现在更有意义了:)有没有办法不用先构造userController就可以做到这一点?@Ralph我唯一能做的就是使用string方法名。。对不起,朋友!等待…
newcallback(Action)
,如果
Action
是UserController中的实例方法。。。这是如何编译的?@Ralph:[Delegates](如
Callback
表示方法,如“可以运行的代码片段”。MethodInfo表示方法,如“具有名称和签名的成员”.我很惊讶没有人这么早说..甚至没有人提到委托!哦..你事先初始化了一个user实例。现在更有意义了:)有没有办法不用先构造userController就可以做到这一点?@Ralph我唯一能做的就是使用string方法名。。对不起,朋友!