我想在运行时使用反射加载一个类型。以下是步骤:
Assembly.LoadFile(assemblyPath);
GetType
方法获取类型Activator.CreateInstance
创建类型实例。以下是我的代码:
Assembly assembly = Assembly.LoadFile(assemblyName);
Type type = assembly.GetType("RomanConerter.Converter");
object obj = Activator.CreateInstance(type);
我面临的问题是最后一行。我的转换器有一个方法名称Add
。但我无法使用obj。
注意:我试图在其他项目中加载的程序集,并且我有hasrd编码路径。
有人可以帮帮我吗?
答案 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)
看起来这可以通过几种方式完成。
dynamic
关键字,因为这将提供对相关对象的后期绑定。答案 6 :(得分:0)
如果您不想使用动态(或使用早期版本的C#),您可以使用一些反射 - 这对于简单的方法调用来说并不复杂:
obj.GetType().GetMethod("MethodName", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Invoke(obj, null);