是否可以将方法的强类型名称作为lambda表达式传递而不提供参数和/或括号?
例如,如果我有以下方法:
public class CalleeClass
{
public void MethodA(obj param1, obj param2)
{
...
}
}
我想通过以下方式将此方法称为:
return new MyClass<CalleeClass>(c => c.MethodA); //Note: no ()'s or arguments
其中 MyClass 将负责使用方法名称作为目标的MVC路由。这里的目标是我们希望能够通过控制器方法使用强类型视图,并且我不想提供&#34; dumb&#34;不能使用的参数。
目前,我使用类似于以下的代码来使用方法名称,但这种样式仍然需要传递假参数和/或括号。
public void MyClass<T>(Expression<Action<T>> action)
{
var methodName = (action.Body as MethodCallExpression).Method.Name;
}
编辑:对于这种混淆感到抱歉,但我最初只是考虑到了我认为你需要的内容而试图简化这个问题,并且这样做会遗漏一些关键信息。这里的最终目标是让MyClass接收泛型类型+ lambda表达式,并且lambda表达式可以传入强类型方法名称而不实例化对象。 -MB
答案 0 :(得分:2)
您实际上可以不带参数传递方法:
class PassActionTest
{
public void Test( )
{
var c = new C();
var myClass = new MyClass(c.MethodA);
}
}
class MyClass
{
public MyClass(Action<object,object> action)
{
string methodName = action.Method.Name;
}
}
class C
{
public void MethodA(object param1, object param2)
{
}
}
编辑:根据Matt Beckman的编辑,不应该实例化包含MethodA的类。我的新解决方案是:
class PassActionTest
{
public void Test()
{
var myClass = new MyClass(c => c.MethodA);
}
}
class MyClass
{
public MyClass(Expression<Func<C, Action<object, object>>> expr)
{
UnaryExpression unaryExpr = (UnaryExpression)expr.Body;
MethodCallExpression methodCallExpr = (MethodCallExpression)unaryExpr.Operand;
ConstantExpression constantExpr = (ConstantExpression)methodCallExpr.Arguments[2];
MethodInfo methodInfo = (MethodInfo)constantExpr.Value;
string methodName = methodInfo.Name;
}
}
class C
{
public void MethodA(object param1, object param2)
{
}
}
分析表达式有点复杂,但我已经测试过它并且有效。
答案 1 :(得分:1)
如果您只是需要方法名称,我建议使用Delegate
(http://msdn.microsoft.com/en-us/library/system.delegate.aspx):
public MyClass(Delegate action)
{
var methodName = action.Method.Name;
}
除了我认为你需要在传递它时指定委托类型时,这是有效的:
{
...
return new MyClass((Action<object,object>)c.MethodA);
}
这将保持所有强类型,以便重构也可以。
答案 2 :(得分:0)
您可以声明与方法MethodA()的签名匹配的委托,并使用委托作为MyClass类的构造函数的参数
public delegate void MethodADelegate(object param1, object param2);
public MyClass(MethodADelegate methodParam)
{
//use the methodParam parameter
}
或者,您可以使用Action&lt;&gt;根据@Olivier
的建议,代表出现在.Net中