【问题标题】:Create delegate via reflection通过反射创建委托
【发布时间】:2011-03-02 17:48:18
【问题描述】:

给定一个包含

的程序集
namespace Foo{public class Bar;}

如何在编译时不引用第一个程序集的情况下从另一个程序集创建Action<Foo.Bar>?

【问题讨论】:

  • “不引用第一个程序集”是什么意思?如果您想使用该程序集中的类型,则需要以某种方式引用它。
  • 对不起,我的意思是没有将其添加为对 Visual Studio 项目的引用。即使用 Assembly.LoadFrom() 来加载它,这样就没有编译时依赖。
  • @LukeH - 编辑问题更清晰。感谢您的意见。
  • 如果由于在编译时没有类型而无法将委托分配给变量,您会怎么处理?你想达到什么目的?
  • @dtb - 在我的场景中,我在源程序集中有一个接受Action<Foo.Bar> 的构造函数。所以我希望创建一个Action<Foo.Bar> 通过反射传递给所述构造函数。

标签: c# reflection .net-3.5 delegates


【解决方案1】:

如果你使用

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

actionType 现在将代表Action&lt;Foo.Bar&gt;。但是,要使用它,您需要继续使用反射,因此您需要找到符合签名void(Foo.Bar) 的MethodInfo,并调用Delegate.CreateDelegate 来创建委托。你需要Delegate.DynamicInvoke 来执行它。

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

有些事情告诉我这不是你想的......

【讨论】:

  • 我会在Delegate.CreateDelegate(actionType, ...); 中的... 中添加什么?我认为您的解决方案是我所需要的,因为无论如何我都会将此委托传递给源程序集中的构造函数。
【解决方案2】:

您不能在调用代码中调用它Action&lt;Foo.Bar&gt;,因为如果您在编译时不引用它,您将无法访问该类型定义。由于委托是逆变的,您可以返回 Action&lt;Object&gt; 并使用它,或者使用 Action&lt;IBar&gt;,其中 IBar 接口在引用的程序集中定义,并由 Foo.Bar 实现。

如果您确实返回了Action&lt;Object&gt;,则必须通过反射使用Foo.Bar 成员(如果使用C# 4.0,则使用dynamic)或将其强制转换为Foo.Bar,其中强制转换代码有参考到定义Foo.Bar 的程序集。

【讨论】:

  • “你不能在你的调用代码中调用它 Action”——是的,我意识到了这一点。回复:逆变 - 抱歉,我没有指定 .NET 3.5。我会修复标签。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-04
  • 2015-11-16
  • 1970-01-01
  • 2019-09-21
相关资源
最近更新 更多