2012-10-10 39 views
1

我想在运行时使用反射来加载类型。下面是步骤:在C#中使用反射在运行时加载类型

  1. 负载使用Assembly.LoadFile(assemblyPath);
  2. 使用GetType方法得到类型
  3. 使用Activator.CreateInstance创建类型的实例的组件。

下面是我的代码:我现在面临

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

问题出在最后一行。我的转换器有一个方法名称Add。但我无法使用obj访问此方法。

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

任何人都可以帮助我吗?

+0

你确定它是'RomanConerter'而不是'RomanConverter'吗? – ThiefMaster

+0

其实它的一个自定义转换器,只是在创建项目时出现拼写错误,将在以后更改 – Jash

+0

@ThiefMaster,这告诉我这只是一个错字......谁知道 – series0ne

回答

1

这一切都取决于

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

obj.Add("stuff"); 
+0

我不知道这是否会工作 - 程序集正在加载LoadFile,它将其中的类型放入一个不同的加载上下文中 - 不知道这是否意味着任何引用的类型不会被强制转换。 – fubaar

+0

而该组件是在不同的负载上下文中 - 我相信它引用的任何程序集都不是,因为它们受制于正常的程序集加载规则 –

+0

@AndrasZoltan它仍然无法正常工作我无法继续访问Add方法与上面的代码。 – Jash

0

你必须明确地投的类型,您要创建:

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

是不会工作的。该类型在编译时不可用。那有趣的基于字符串的演员是什么?这不是C#。 –

+0

我不能那样做。由于我正在加载的程序集名称来自运行时。所以我不知道哪个程序集将被加载。这取决于使用输入 – Jash

2

动态此:

dynamic obj = Activator.CreateInstance(type); 
+0

没有动态不会工作,事实上它不工作 – Jash

+0

@Jash:你为什么说它不工作? –

+0

你能详细解释一下吗?我使用动态绑定,然后我调用Add方法。像下面的 dynamic obj = Activator.CreateInstance(type); obj.Add - >但这种添加方法不可访问。我看不到这种Add方法的任何插入提示。 – Jash

1

你有两个选择:dynamic或大量反射。

试试这个:

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

你可以在这里读到它:Type.InvokeMember

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获取对象你只是中科院t至ICanAdd

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

现在您可以调用该方法。

+0

这也有效,但我喜欢@Andras Zoltan所说的东西。 – Jash

0

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

  1. 实现您的自定义类型的接口,并具有可在编译时的界面。
  2. 使用dynamic关键字,因为这将提供对有问题的对象的迟绑定。
0

如果你不想使用动态(或正在使用的C#的早期版本),你可以使用一些反思 - 这不是一个简单的方法调用过于复杂:

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