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 nullin 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.CreateInstancemethod 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 AssemblyNameparameter null).
如果您按照此处的答案中的建议调用它:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName),那么它会返回一个ObjectHandle,您需要调用Unwrap()它来获取您的对象。当尝试调用在不同程序集中定义的方法时,此重载很有用(顺便说一句,您可以在当前程序集中使用此重载,只需将AssemblyName参数留空)。
Now, I found that the suggestion above to use typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedNamefor AssemblyNameactually 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).AssemblyQualifiedNamefor的建议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();

