2010-06-11 161 views
6

代表鑑於包含創建通過反射

namespace Foo{public class Bar;} 

組裝我怎麼能建立從另一個組件的Action<Foo.Bar>沒有在編譯時引用第一組件?

+1

你什麼意思通過做「無參考第一集結號」?如果你想使用該程序集中的類型,那麼你需要以某種方式引用它。 – LukeH 2010-06-11 15:56:53

+0

對不起,我的意思是沒有添加它作爲對Visual Studio項目的參考。即使用Assembly.LoadFrom()來加載它,以便不存在編譯時間依賴性。 – dss539 2010-06-11 15:59:13

+0

@LukeH - 編輯的問題要清楚一點。感謝您的意見。 – dss539 2010-06-11 16:00:54

回答

10

如果使用

Type barType = Type.GetType("Foo.Bar, whateverassembly"); 
Type actionType = typeof(Action<>).MakeGenericType(barType); 

actionType現在將代表Action<Foo.Bar>。但是,要使用它,您需要持續使用反射,因此您需要找到符合簽名void(Foo.Bar)MethodInfo,然後致電Delegate.CreateDelegate來創建委託。你需要Delegate.DynamicInvoke來執行它。

Delegate call = Delegate.CreateDelegate(actionType, ...); 
... 
call.DynamicInvoke(someBar); 

個聲音告訴我,這不是你在想什麼......

+0

我會在'Delegate.CreateDelegate(actionType,...);'中放置什麼?我認爲你的解決方案是我所需要的,因爲我會將這個委託傳遞給源程序集中的構造函數。 – dss539 2010-06-11 16:36:24

+0

謝謝,我解決了我的問題。非常感謝您的幫助。 – dss539 2010-06-11 16:58:38

3

在調用代碼中不能調用Action<Foo.Bar>,因爲如果不在編譯時引用它,則無法訪問該類型定義。由於代表是逆向的,因此您可以返回Action<Object>並使用它,或使用Action<IBar>,其中IBar接口在引用程序集中定義,並由Foo.Bar實現。

如果這樣做返回一個Action<Object>,你要麼有(如果使用C#4.0或dynamic)使用經由反射Foo.Bar構件或使用它投射到Foo.Bar其中,鑄代碼具有該組件的引用,其中Foo.Bar被定義。

+0

「你不能在你的調用代碼中把它叫做Action 」 - 是的,我意識到這一點。回覆:逆變 - 對不起,我沒有指定.NET 3.5。我會修復這些標籤。 – dss539 2010-06-11 16:09:22