2010-06-24 30 views
1

讓我試着舉一個小例子。MethodInfo.Invoke內部有一個委託Object [] params

class Session (
    public delegate string CleanBody(); 
    public static void Execute(string name, string q, CleanBody body) ... 

可以使用,如:

Session.Execute("foo", "bar", delegate() { string x="beep"; /* whatever*/ return x; }); 

但是如果我需要運行是通過MethodInfo.Invoke - 在不同的dll沒有類型的依賴關係兩種方式。像:

Type type = Type.GetType("Bla.Session, FooSessionDll", true); 
MethodInfo methodInfo = type.GetMethod("Execute"); 

Object [] args = { "foo", "bar", delegate() // Doesn't compile, now that ? 
{ 
    string x="beep"; /* whatever*/ return x; 
} 

methodInfo.Invoke("Trial Execution :-)", args); 

無論伎倆/施放將應用於它必須是這樣的,它仍然會到達執行作爲一個真正的代表。實際委託(或多個)可能有更復雜的簽名等等,等等

+0

請詳細解釋爲什麼你想做這樣一個令人困惑的事情。可能有更好的方法。 – ChaosPandion 2010-06-24 04:04:51

+0

不幸的是,與代表類型鑄造沒有太大的餘地。我不得不首先質疑總體架構。沒有明確的推理背後有些問題可能沒有正確的答案。 – SamuelWarren 2010-06-24 04:44:32

+0

沒有什麼讓人困惑的 - 只是試圖通過重選來複制確實來的調用,如果它取決於類型依賴性。就這樣。 在CLR中有幾個specilazed類,它們將代表「包裝」成Object-compat類非常有限 - 我只需要更多的常規變體。所以指向任何私有/內部類mucho讚賞以及:-) B方(Session.Execute)是一個巨大的lageacy包,仍然有A端加載的DLL(做MethodInfo.Invoke)之間的「客戶」。 – ZXX 2010-06-24 07:43:54

回答

0

OK,找到了解決辦法:Func<<TResult>>,和Func鍵模板的全系列產品。在這個例子而言,我張貼,轉換的執行(...)的簽名:

public static void Execute(string name, string q, Func<string> body) 

在功能上等同於一個具有明確指定的代表即承擔它的類型依賴仍然可以使用

任何代碼
Session.Execute("foo", "bar", delegate() { ... }); 

與零碼變化,任何獨立的dll現在可以這樣做:

Func<string> d = delegate() { .....} 

並在Object[]將它作爲正常的參數。

有另一個線程問:「有什麼了不起Func<>」 - 嗯,這是:-)

它可以打破依賴和不聖潔的結盟與現有使用它的代碼零代碼的變化。一個條件是現有代碼使用匿名方法(如示例中)而不使用舊式顯式委託創建。

0
private static class Invoker 
{ 
    private static string Method() 
    { 
     return "beep"; 
    } 

    public static object Invoke() 
    { 
     Type type = Type.GetType("Bla.Session, FooSessionDll", true); 
     MethodInfo methodInfo = type.GetMethod("Execute"); 
     Type delegateType = methodInfo.GetParameters()[2].ParameterType; 
     Delegate delegateInstance = Delegate.CreateDelegate(delegateType, typeof(Invoker).GetMethod("Method")); 
     object[] args = new object[] { "foo", "bar", delegateInstance }; 
     return methodInfo.Invoke(null, args); 
    } 
} 
+0

這將注入從「其他」DLL的類型依賴。這不是一個學術問題:-) DLL(使用調用)應該conpile並運行,即使DLL B(與Session.Execute)根本不存在。任何與匿名類型可能? – ZXX 2010-06-24 03:47:25

+0

@zb_z - 我認爲這可能對你有幫助,雖然你的問題不是很清楚。 – ChaosPandion 2010-06-24 04:03:55

+0

嗯,那methodInfo.GetParameters()[2] .ParameterType看起來很有前途,如果有辦法將delegate(){....}給它。涉及到的實際委託從關閉中使用了相當多的對象,所以它不能被靜態方法完全取代,除非我們已經治癒了我們沒有的方法:-) – ZXX 2010-06-24 08:52:46

相關問題