如何正确转换通过反射创建的对象

Ben*_*ins 10 .net c# reflection

我试图围绕反射,所以我决定将插件功能添加到我正在编写的程序中.理解一个概念的唯一方法是让你的手指变脏并编写代码,所以我选择了创建一个由IPlugin和IHost接口组成的简单接口库,一个实现IPlugin的类的插件实现库,以及一个简单的接口库.实例化IHost实现类的控制台项目,该类实现了插件对象的简单工作.

使用反射,我想迭代我的插件实现dll中包含的类型并创建类型的实例.我能够使用此代码成功实例化类,但我无法将创建的对象强制转换为接口.

我尝试了这段代码,但我无法像我预期的那样投射对象o.我使用调试器完成了整个过程,并调用了正确的构造函数.快速查看对象o向我展示了它具有我期望在实现类中看到的字段和属性.

loop through assemblies
  loop through types in assembly
    // Filter out unwanted types
    if (!type.IsClass || type.IsNotPublic || type.IsAbstract )
      continue;
    // This successfully created the right object
    object o = Activator.CreateInstance(type);
    // This threw an Invalid Cast Exception or returned null for an "as" cast
    // even though the object implemented IPlugin      
    IPlugin i = (IPlugin) o;
Run Code Online (Sandbox Code Playgroud)

我使用这个代码.

using System.Runtime.Remoting;
ObjectHandle oh = Activator.CreateInstance(assembly.FullName, type.FullName);
// This worked as I intended
IPlugin i = (IPlugin) oh.Unwrap();
i.DoStuff();
Run Code Online (Sandbox Code Playgroud)

这是我的问题:

  1. Activator.CreateInstance(Type t)返回一个对象,但我无法将该对象强制转换为该对象实现的接口.为什么?
  2. 我应该使用CreateInstance()的不同重载吗?
  3. 什么是反射相关的提示和技巧?
  4. 我只是没有得到一些关键的反思部分吗?

lub*_*sko 4

我只是在这里猜测,因为从您的代码来看,您在哪里定义 IPlugin 接口并不明显,但如果您无法在主机应用程序中进行强制转换,那么您可能在主机程序集中有 IPlugin 接口,然后同时在你的插件程序集。这行不通。

要实现这项工作,最简单的方法是在主机程序集中将 IPlugin 接口标记为公共,然后让插件程序集引用主机应用程序程序集,这样两个程序集都可以访问相同的接口

  • 对于一个简单的应用程序来说可能有点矫枉过正,但另一种方法是创建一个单独的库,其中只包含接口并从所有需要了解它的人中引用它:o) (2认同)