2010-06-11 85 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