当前位置:  开发笔记 > 编程语言 > 正文

只知道类名创建一个对象?

如何解决《只知道类名创建一个对象?》经验,为你挑选了3个好方法。

我有一组课程,每一个课程都是做同样工作的不同策略.

namespace BigCorp.SuperApp
{
    public class BaseClass { }
    public class ClassA : BaseClass { }
    public class ClassB : BaseClass { }
}

选择使用哪种策略是可配置的.我想在app.config文件中只配置类名'ClassB'而不是完整的类型名称'BigCorp.SuperApp.ClassB'.


   
      
   

但是,反射调用失败,因为它们期望完整的类型名称,尤其是

Type t = Type.GetType("ClassB"); // results in t == null
BaseClass c = Activator.CreateInstance(t) as BaseClass; // fails

如何在仅配置类名时才能使其工作?将名称空间连接到完整类型名称的类名?是否有其他反射调用有效?

如果你认为这是无用的,我希望配置包含完整的类型名称,我对这个解决方案持开放态度!只是提供说服我的理由.

(我不会从此程序集/命名空间外部加载类型)



1> Marc Gravell..:

使用程序集限定名称,或获取程序集并使用Assembly.GetType(name).在这种情况下,由于您需要配置文件中的类型,因此assembly-qualified是一种有效的方法 - 但是因为您知道所有类型都在同一个程序集中:

Assembly assembly = typeof(SomeKnownType).Assembly; // in the same assembly!
Type type = assembly.GetType(name); // full name - i.e. with namespace (perhaps concatenate)
object obj = Activator.CreateInstance(type);

静态Type.GetType(string)具有经常导致混淆的探测规则......它查看调用程序集和一些系统程序集 - 但不是所有已加载的程序集.



2> Bryan Watts..:

既然您知道所有类都来自同一个命名空间,请配置一次并使用它:


   
      
   

编辑:我将名称更改为以更好地表示该属性的含义.



3> Kyle Trauber..:
(I will not be loading a type from outside this assembly/namespace)

由于上面这一行,可以安全地假设您知道命名空间是什么.你做不到这样的事情:

Type t = Type.GetType("Namespace." + className); 
BaseClass c = Activator.CreateInstance(t) as BaseClass; 

如果您希望将来可能能够添加其他策略类(可能通过其他程序集),则需要完全限定类名.无论如何,这是建议的,因为您可以为您的应用程序提供增强的可扩展性.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有