2013-01-14 15 views
4

這裏有一個類似的問題:通路方法/返回類型參數在C#

Pass Method as Parameter using C#

它假定你知道方法的參數和返回類型。我想做一些有點不同的事情。我希望創建一個版本的System.Reflection的.GetMethod(串),與其花費lambda函數的 - 所以不是:

MethodInfo methodInfo = typeof(MyClass).GetMethod("AddThing"); 

我可以用一個更編譯安全:

MethodInfo methodInfo = ReflectionHelper.GetMethod<MyClass>(mc => mc.AddThing); 

所以如果ReflectionHelper知道參數計數和返回類型事先答案是簡單的上下的 - 例如,如果它有沒有參數和返回的字符串:

public static MethodInfo GetMethod<T, TReturn>(Expression<Func<T, Func<TArg, TReturn>>> expr) 
{ 
    return ((MethodCallExpression)expr.Body).Method; 
} 

只是我不知道做T他事先提供了參數計數/返回類型,並且我想避免僅使用覆蓋大多數但不是所有情況的20個重載發送垃圾郵件。

那麼,我該怎麼做?

+0

可以'動態'幫忙嗎? – Johnny5

+0

如果您不知道它接受的參數,您打算如何傳遞給該方法以嘗試調用它? – Servy

+0

@ Johnny5我不明白。當它被調用時,這仍然需要一個固定的簽名,或者至少是一個符合提供參數的簽名。 – Servy

回答

3

您尚未在lambda mc => mc.AddThing中指定方法 - 您已指定方法組。

你可以做的是在表達式中寫一個方法調用 - 儘管它永遠不會被執行,所以參數只需指定你想要的超載。

因此,要使用它,你可以這樣寫:

MethodInfo mi = GetMethod<MyClass>(mc => mc.AddThing(null)); 

則表達式可能只是一個Action,而不是一個Func

public static MethodInfo<T>(Expression<Action<T>> expr) 
{ 
    return ((MethodCallExpression) x.Body).Method; 
} 

一如既往地與表達的檢查,這是容易運行時錯誤,如果lambda不是預期的形式,但它是擺脫「魔術」字符串正確方向的一步。

+0

這是朝着正確方向邁出的一步 - 我不喜歡傳遞假參數以指定方法,儘管鍵入會稍微簡單一些,因爲它會涉及IDE的更多幫助,而不是我下面發佈的類似答案。然而,不幸的是,沒有答案讓我達到我的目標。 –

0

我使用的是現在,我會打電話的解決方法「的垃圾郵件的做法,」是醜陋的,但在有限的一組場景功能:

public class ReflectionHelper<T> 
{ 
    public MethodInfo GetMethod<TA1>(Expression<Func<T, Func<TA1>>> expr) 
    { 
     return ((MethodCallExpression)expr.Body).Method; 
    } 
    public MethodInfo GetMethod<TA1, TA2>(Expression<Func<T, Action<TA1, TA2>>> expr) 
    { 
     return ((MethodCallExpression)expr.Body).Method; 
    } 
    public MethodInfo GetMethod<TA1, TA2, TA3>(Expression<Func<T, Action<TA1, TA2, TA3>>> expr) 
    { 
     return ((MethodCallExpression)expr.Body).Method; 
    } 
    . . . // And more 
} 

而且如此下去,到指定可能的動作和功能的各種參數計數的長列表。這使我其實這樣使用它:

(new ReflectionHelper<MyClass>()).GetMethod<string>(mc => mc.SaySomething).Invoke("Hi"); 

所以這是近十歲上下 - 我去只是叫名字的方法,我也避免將假論據爲了做到這一點,但我仍然得到抓住了它的論點類型 - 比我希望的更復雜。在同名多個方法重載的情況下,傳遞參數的類型會將方法列表縮小爲一個特定的重載。

我仍然對更簡單的東西感興趣,可以採取一種方法,就像我的問題一樣。在方法超載的情況下它會很模糊,但標準的.GetMethod(字符串)也是如此。