使用C#中的反射在运行时加载类型

时间:2012-10-10 10:39:54

标签: c# reflection

我想在运行时使用反射加载一个类型。以下是步骤:

  1. 使用Assembly.LoadFile(assemblyPath);
  2. 加载程序集
  3. 使用GetType方法获取类型
  4. 使用Activator.CreateInstance创建类型实例。
  5. 以下是我的代码:

    Assembly assembly = Assembly.LoadFile(assemblyName);
    Type type = assembly.GetType("RomanConerter.Converter");
    object obj = Activator.CreateInstance(type);
    

    我面临的问题是最后一行。我的转换器有一个方法名称Add。但我无法使用obj。

    访问此方法

    注意:我试图在其他项目中加载的程序集,并且我有hasrd编码路径。

    有人可以帮帮我吗?

7 个答案:

答案 0 :(得分:2)

动态这个:

dynamic obj = Activator.CreateInstance(type);

答案 1 :(得分:1)

您有两种选择:dynamic或大量反思。

试试这个:

Assembly assembly = Assembly.LoadFile(assemblyName);
Type type = assembly.GetType("RomanConerter.Converter");
dynamic obj = Activator.CreateInstance(type);

obj.Add("stuff");

答案 2 :(得分:1)

如果您更喜欢使用反射,可以按如下方式使用它:

Type objType = obj.GetType();
objType.InvokeMember("Add", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
    null, obj, new object[] { /*comma-separated arguments here*/ });

您可以在此处阅读:Type.InvokeMember

答案 3 :(得分:1)

这完全取决于您的调用应用程序中是否可以使用类型RomanConverter.Converter(即包含您发布的代码)。如果是这样,那么你就是投了。

如果没有 - 那么你可以使用反射来延迟绑定方法(正如其他人所说的那样)或者使用dynamic,但是你可以更好地使用公共基础或接口:

/* common interface used in both your code and the external DLL */
public interface ICanAdd {
  object Add(object source);
}

(我在这里猜测签名)

然后将您的插件类型更改为:

namespace RomanConverter {
  public class Converter : ICanAdd {
    object Add(object source){
      //TODO: implement
    }
  }
}

现在当你从Activator.CreateInstance获得对象时,你只需要转换为ICanAdd

ICanAdd obj = (ICanAdd)Activator.CreateInstance(type);

现在您可以调用该方法。

答案 4 :(得分:0)

您必须明确强制转换为您正在创建的类型:

RomanConerter.Converter obj = (RomanConerter.Converter)Activator.CreateInstance(type);

答案 5 :(得分:0)

看起来这可以通过几种方式完成。

  1. 在自定义类型中实现接口,并在编译时使用该接口。
  2. 使用dynamic关键字,因为这将提供对相关对象的后期绑定。

答案 6 :(得分:0)

如果您不想使用动态(或使用早期版本的C#),您可以使用一些反射 - 这对于简单的方法调用来说并不复杂:

obj.GetType().GetMethod("MethodName", System.Reflection.BindingFlags.Public |  System.Reflection.BindingFlags.Instance).Invoke(obj, null);