【问题标题】:How do I instantiate a class given its string name?如何实例化一个给定字符串名称的类?
【发布时间】:2016-06-05 12:34:54
【问题描述】:

我有一个抽象类,我想将它初始化为一个扩展它的类。

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

除此之外……

String childClassString;
MyAbstractClass myObject;

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

我该怎么做?基本上我该如何摆脱这里的 if 语句?

【问题讨论】:

标签: c# reflection polymorphism


【解决方案1】:

查看 Activator.CreateInstance()。

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

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

【讨论】:

  • 工作就像一个魅力。如果有人在获取完全限定名称时遇到问题,这段代码很有帮助 ' string typex = typeof(classname).AssemblyQualifiedName;
  • 尽管GetTypetypeName 参数的文档说“类型的程序集限定名称”,但您实际上并不需要包含程序集名称。如果类型在调用程序集中,则只需命名空间限定的类型名称就足够了。
【解决方案2】:

我相信这应该可行:

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

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

编辑:忘记投到MyAbstractClass

【讨论】:

    【解决方案3】:

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

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

    如果您按照此处答案中的建议调用它:Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName),那么它会返回一个 ObjectHandle,并且您需要在其上调用 Unwrap() 以获取您的对象。当尝试调用在不同程序集中定义的方法时,此重载很有用(顺便说一句,您可以在当前程序集中使用此重载,只需将 AssemblyName 参数留空)。

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

    我做的工作如下:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-23
      相关资源
      最近更新 更多