我有一个抽象类,我想把它推广到一个扩展它的类。
我将子类名称作为字符串。
除此之外......
String childClassString;
MyAbstractClass myObject;
if (childClassString = "myExtenedObjectA")
myObject = new ExtenedObjectA();
if (childClassString = "myExtenedObjectB")
myObject = new ExtenedObjectB();
我该怎么做?基本上我如何摆脱这里的if语句?
答案 0 :(得分:109)
查看Activator.CreateInstance()。
myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
或
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
答案 1 :(得分:20)
我相信这应该有效:
myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);
第一个参数中的null
默认为当前正在执行的程序集。有关更多参考:MSDN
编辑:忘了投放到MyAbstractClass
答案 2 :(得分:5)
我在这里实现一些答案时遇到了一些困难,因为我试图从不同的程序集中实例化一个对象(但是在同一个解决方案中)。所以我想我会发布我发现的工作。
首先,Activator.CreateInstance
方法有几个重载。如果您只是调用Activator.CreateInstance(Type.GetType("MyObj"))
,则假定该对象已在当前程序集中定义,并返回MyObj
。
如果您按照此处的答案中的建议调用它:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName)
,则它会返回ObjectHandle
,您需要在其上调用Unwrap()
来获取您的对象。当尝试调用在不同程序集中定义的方法时,此重载很有用(顺便说一句,您可以在当前程序集中使用此重载,只需将AssemblyName
参数保留为null)。
现在,我发现上面针对typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName
使用AssemblyName
的建议实际上给了我错误,我无法让它发挥作用。我得System.IO.FileLoadException
(无法加载文件或程序集......)。
我所做的工作如下:
var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject");
MyObject obj = (MyObject)container.Unwrap();
obj.DoStuff();