使用强类型方法作为参数而不指定参数

时间:2011-11-08 00:17:11

标签: c# linq asp.net-mvc-3 delegates

是否可以将方法的强类型名称作为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

3 个答案:

答案 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中