2010-02-11 102 views
48

我有一个抽象类,我想将它初始化为一个扩展它的类。c#实例化字符串中的类

我有孩子类名字符串。

除此之外...

String childClassString; 
MyAbstractClass myObject; 

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

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

+1

为什么你需要一个字符串实例化类?根据你的情况,可能会有“更清洁”的解决方案,特别是如果你不愿意使用反射。 – 2010-02-11 21:28:04

+1

@SylvestreEquy但是也许在别人的情况下,这只是解决方案...... SO上的问题不仅仅为那些问他们的人提供服务。 – 2014-11-12 17:42:06

回答

90

看看Activator.CreateInstance()。

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

var type = Type.GetType("MyFullyQualifiedTypeName"); 
var myObject = (MyAbstractClass)Activator.CreateInstance(type); 
+6

工作就像一个魅力。如果任何人在获取完全限定名称时遇到问题,这段代码是有用的'string typex = typeof(classname).AssemblyQualifiedName; – 2013-06-21 10:50:16

+0

尽管'typeName'参数的'GetType'文档显示“该类型的程序集限定名称”,您实际上不需要包含程序集名称。如果类型位于调用程序集中,则仅限名称空间限定的类型名称就足够了。 – 2015-05-22 15:43:21

18

我认为这应该工作:

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

在第一个参数默认为当前执行的程序集的null。欲了解更多参考:MSDN

编辑:忘了投给MyAbstractClass

1

我不得不实施一些问题的答案在这里,因为我试图从不同的组件实例化对象有些困难(但在相同的解决方案)。所以我想我会发布我发现的工作。

首先,Activator.CreateInstance方法有几个重载。如果您只需拨打Activator.CreateInstance(Type.GetType("MyObj")),即假定该对象在当前程序集中定义,并返回MyObj

如果你把它作为在这里的答案推荐:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName),那么它,而不是返回一个ObjectHandle,你需要调用它的Unwrap()让你的对象。当尝试调用另一个程序集中定义的方法时,此重载很有用(顺便说一下,您可以在当前程序集中使用此重载,只需将参数AssemblyName保留为空)。

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

我没去工作如下:

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