如何通过类名字符串实例化一个类?

87

我有一个抽象类,我想把它初始化为继承它的类。

我有子类的名称作为字符串。

除此之外...

String childClassString;
MyAbstractClass myObject;

if (childClassString = "myExtenedObjectA")
    myObject = new ExtenedObjectA();
if (childClassString = "myExtenedObjectB")
    myObject = new ExtenedObjectB();

我该怎么做?基本上,我如何摆脱这里的if语句?


这个回答解决了你的问题吗?如何通过字符串创建一个类的实例 - GSerg
3个回答

142

看一下Activator.CreateInstance()。

myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
或者
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);

9
运作得非常好。如果有人在获取完整的类名时遇到问题,这段代码很有用:' string typex = typeof(classname).AssemblyQualifiedName; - Sanjit Misra
2
尽管 GetType 文档中对于其 typeName 参数的说明是“类型的程序集限定名称”,但实际上您并不需要包含程序集名称。如果该类型在调用程序集中,则只需使用命名空间限定的类型名称即可。 - Edward Brey

24

我相信这应该可以工作:

myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);

第一个参数中的 null 默认为当前执行的程序集。更多信息请参考:MSDN

编辑:忘记将其转换为 MyAbstractClass


10

我曾经在这里实现某些答案时遇到了一些困难,因为我试图从不同的程序集(但在同一个解决方案中)实例化对象。所以我想发帖说明我找到的解决方法。

首先,Activator.CreateInstance 方法有几个重载。如果只调用 Activator.CreateInstance(Type.GetType("MyObj")) ,那就假定该对象定义在当前程序集中,并返回一个MyObj

如果按照这里的建议调用它:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName),那么它会返回一个ObjectHandle,您需要在其上调用Unwrap()才能获得您的对象。当尝试调用在另一个程序集中定义的方法时,此重载非常有用(顺便说一下,您可以在当前程序集中使用此重载,只需将AssemblyName参数设置为null即可)。

现在,我发现上面建议使用typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName作为AssemblyName实际上会给我带来错误,而我无法使其工作。我得到了System.IO.FileLoadException (无法加载文件或程序集...)。

我最终让它工作的方法如下:

var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject");
MyObject obj = (MyObject)container.Unwrap();
obj.DoStuff();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接