C# 如何实例化一个给定字符串名称的类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2247598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I instantiate a class given its string name?
提问by ctrlShiftBryan
I have an abstract class and I want to initalize it to a class that extends it.
我有一个抽象类,我想将它初始化为一个扩展它的类。
I have the child classes name as a string.
我将子类名称作为字符串。
Besides this...
除此以外...
String childClassString;
MyAbstractClass myObject;
if (childClassString = "myExtenedObjectA")
myObject = new ExtenedObjectA();
if (childClassString = "myExtenedObjectB")
myObject = new ExtenedObjectB();
How can I do this? Basically how do I get rid of the if statements here?
我怎样才能做到这一点?基本上我如何摆脱这里的 if 语句?
采纳答案by Seth Petry-Johnson
Look at Activator.CreateInstance().
看看 Activator.CreateInstance()。
myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
or
或者
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
回答by IAbstract
I believe this should work:
我相信这应该有效:
myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);
The null
in the first parameter defaults to the current executing assembly. For more reference: MSDN
第null
一个参数中的默认为当前正在执行的程序集。更多参考:MSDN
edit: forgot to cast to MyAbstractClass
编辑:忘了投 MyAbstractClass
回答by Kevin Fichter
I had some difficulty implementing some of the answers here because I was trying to instantiate an object from a different assembly (but in the same solution). So I thought I'd post what I found to work.
我在这里实现一些答案时遇到了一些困难,因为我试图从不同的程序集(但在相同的解决方案中)实例化一个对象。所以我想我会发布我发现的工作。
First, the Activator.CreateInstance
method has several overloads. If you just call Activator.CreateInstance(Type.GetType("MyObj"))
, that assumes the object is defined in the current assembly, and it returns a MyObj
.
首先,该Activator.CreateInstance
方法有几个重载。如果您只是调用Activator.CreateInstance(Type.GetType("MyObj"))
,则假定该对象已在当前程序集中定义,并返回一个MyObj
.
If you call it as recommended in the answers here: Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName)
, then it instead returns an ObjectHandle
, and you need to call Unwrap()
on it to get your object. This overload is useful when trying to call a method defined in a different assembly (BTW, you can use this overload in the current assembly, just leave the AssemblyName
parameter null).
如果您按照此处的答案中的建议调用它:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName)
,那么它会返回一个ObjectHandle
,您需要调用Unwrap()
它来获取您的对象。当尝试调用在不同程序集中定义的方法时,此重载很有用(顺便说一句,您可以在当前程序集中使用此重载,只需将AssemblyName
参数留空)。
Now, I found that the suggestion above to use typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName
for AssemblyName
actually gave me errors, and I could not get that to work. I'd get System.IO.FileLoadException
(could not load file or assembly...).
现在,我发现上面使用typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName
for的建议AssemblyName
实际上给了我错误,我无法让它起作用。我会得到System.IO.FileLoadException
(无法加载文件或程序集...)。
What I did get to work is as follows:
我所做的工作如下:
var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject");
MyObject obj = (MyObject)container.Unwrap();
obj.DoStuff();