C# 如何引用方法?
我正在尝试为web应用程序创建路由器(是的,我知道解决方案已经存在) 到目前为止,我得到了这个: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)
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与该正则表达式匹配时,它应该调用classcontroller
中的方法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方法名。。对不起,朋友!