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

ctr*_*yan 63 c# reflection polymorphism

我有一个抽象类,我想把它推广到一个扩展它的类.

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

除此以外...

String childClassString;
MyAbstractClass myObject;

if (childClassString = "myExtenedObjectA")
    myObject = new ExtenedObjectA();
if (childClassString = "myExtenedObjectB")
    myObject = new ExtenedObjectB();
Run Code Online (Sandbox Code Playgroud)

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

Set*_*son 113

看看Activator.CreateInstance().

myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
Run Code Online (Sandbox Code Playgroud)

要么

var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
Run Code Online (Sandbox Code Playgroud)

  • 工作就像一个魅力.如果任何人在获得完全限定名称时遇到问题,这段代码是有用的'string typex = typeof(classname).AssemblyQualifiedName; (6认同)
  • 尽管其“typeName”参数的“GetType”文档显示“类型的程序集限定名称”,但您实际上不需要包含程序集名称。如果该类型位于调用程序集中,则只需命名空间限定的类型名称就足够了。 (2认同)

IAb*_*act 21

我相信这应该有效:

myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);
Run Code Online (Sandbox Code Playgroud)

null一个参数中的默认值是当前正在执行的程序集.有关更多参考:MSDN

编辑:忘了投了 MyAbstractClass


Kev*_*ter 5

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

首先,该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();
Run Code Online (Sandbox Code Playgroud)