2011-11-08 31 views
5

是否有可能將方法的強類型名作爲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使用方法名稱作爲目標進行路由。這裏的目標是我們希望能夠通過控制器方法使用強類型視圖,並且我不想提供不被使用的「啞」參數。

目前,我使用類似於以下代碼的代碼來使用方法名稱,但是這種風格仍然需要傳遞假參數和/或括號。

public void MyClass<T>(Expression<Action<T>> action) 
{ 
    var methodName = (action.Body as MethodCallExpression).Method.Name; 
} 

編輯:很抱歉的混亂,但我最初試圖通過簡化只包括了我認爲你需要,並在這樣做冷落的一些關鍵信息的問題。這裏的最終目標是使MyClass接收一個泛型類型+ lambda表達式,並且lambda表達式可以傳遞強類型方法名稱而不實例化一個對象。 -MB

+0

你不能設置可選參數嗎?另外:MethodCallExpression將不會工作,除非它有括號我很確定。 – chemicalNova

+0

參數不啞巴;它們被編譯器使用...... –

+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) 
    { 
    } 
} 

編輯:根據馬特貝克曼的編輯,包含治法類不應該被實例化。我的新解決方案是:

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) 
    { 
    } 
} 

分析表達式有點複雜,但我已經測試了它,它的工作原理。

+0

在試圖簡化這裏的問題,我想我忘了補充說這行應該是:_return new MyClass (c => c.MethodA)_,因爲我不想實例化類MethodA方法。查看上面的更改。 –

+0

@MattBeckman:查看編輯原始答案。 –

+1

請參閱[此評論](http://stackoverflow.com/questions/8225302/get-the-name-of-a-method-using-an-expression#comment30751822_8228144)和[本答案](http:// stackoverflow .com/a/26976055/1270174)用於v4.5運行時。 –

0

可以聲明一個代表匹配方法治法(簽名),並使用該委託作爲參數傳遞給MyClass的類的構造函數

public delegate void MethodADelegate(object param1, object param2); 

public MyClass(MethodADelegate methodParam) 
{ 
    //use the methodParam parameter 
} 

或者,也可以使用操作<>委託存在於.Net建議@Olivier

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

這會保持它的所有強類型,從而重構將工作了。

相關問題