如何根据字符串名称实例化一个类?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何根据字符串名称实例化一个类?相关的知识,希望对你有一定的参考价值。

我有一个抽象类,我想将它初始化为扩展它的类。

我将子类名称作为字符串。

除此以外...

String childClassString;
MyAbstractClass myObject;

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

我怎样才能做到这一点?基本上我如何摆脱这里的if语句?

答案

看看Activator.CreateInstance()。

myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");

要么

var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
另一答案

我相信这应该有效:

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

第一个参数中的null默认为当前正在执行的程序集。欲了解更多信息,请访问:MSDN

编辑:忘了施放给MyAbstractClass

另一答案

我在这里实现一些答案时遇到了一些困难,因为我试图从不同的程序集中实例化一个对象(但是在同一个解决方案中)。所以我想我会发布我发现的工作。

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

如果你按照这里的答案中的建议调用它:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName),那么它会返回一个ObjectHandle,你需要在它上面调用Unwrap()来获取你的对象。当尝试调用在不同程序集中定义的方法时,此重载很有用(顺便说一句,您可以在当前程序集中使用此重载,只需将AssemblyName参数保留为null)。

现在,我发现上面使用typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedNameAssemblyName的建议实际上给了我错误,我无法让它工作。我得到System.IO.FileLoadException(无法加载文件或程序集......)。

我做的工作如下:

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

以上是关于如何根据字符串名称实例化一个类?的主要内容,如果未能解决你的问题,请参考以下文章

PHP中如何获得当前类的名称,而实例化后获取子类的名称

创建片段而不从 java 代码实例化它

如何在 JavaScript 中从字符串实例化一个类

有没有办法在 Java 中按名称实例化一个类?

Android - 试图实例化一个不是片段的类

Python怎么排序字典,当字典里的值都是一个类的实例化对象,键为不同的字符串,根据实例化对象的值x排序