【问题标题】:Use string value to create new instance使用字符串值创建新实例
【发布时间】:2011-02-16 05:16:16
【问题描述】:

我有几个类:SomeClass1、SomeClass2。

如何使用字符串中的类名创建这些类之一的新实例?

通常,我会这样做:

var someClass1 = new SomeClass1();

如何从以下创建此实例:

var className = "SomeClass1";

我假设我应该使用 Type.GetType() 或其他东西,但我想不通。

谢谢。

【问题讨论】:

  • 是否有一组已知的类你想要这样做?或者可以在您的代码中以这种方式使用任何 .NET 类吗?换句话说,如果我让你列出所有这些类,你能轻松做到吗?
  • 我有一个类文件夹(文件名与类名匹配)。我正在使用 T4 模板循环目录,删除“.cs”并尝试创建每个类的实例。

标签: c# asp.net oop reflection types


【解决方案1】:

为什么不依赖注入框架? Sprint.Net、Structure Map、NInject 等依赖注入框架很好地处理了这类东西.....

【讨论】:

    【解决方案2】:

    首先你需要通过reflection获取类型,然后你可以使用Activator创建它。

    要获取类型,首先要弄清楚它所在的程序集。有关运行代码的当前程序集,请参阅Assembly.GetExecutingAssembly()。对于当前 AppDomain 中加载的所有程序集,请参阅 AppDomain.CurrentDomain.GetAssemblies()。否则,请参阅Assembly.LoadFrom

    然后,如果你有一个类名但没有命名空间,你可以通过Assembly.GetTypes()枚举你的程序集中的类型。

    最后,使用Activator.CreateInstance 创建类型。

    using System;
    using System.Linq;
    using System.Reflection;
    
    namespace ReflectionTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Assembly thisAssembly = Assembly.GetExecutingAssembly();
                Type typeToCreate = thisAssembly.GetTypes().Where(t => t.Name == "Program").First();
    
                object myProgram = Activator.CreateInstance(typeToCreate);
    
                Console.WriteLine(myProgram.ToString());
            }
        }
    }
    

    【讨论】:

      【解决方案3】:
      Assembly assembly = Assembly.LoadFrom("SomeDll.dll");    
      var myinstance = assembly.CreateInstance("SomeNamespace.SomeClass1");
      

      【讨论】:

      • 仅当该类不在命名空间中时才有效,否则您需要类的全名才能使CreateInstance 工作。
      • 很好,离开了命名空间
      • 在当前 AppDomain 中加载程序集是一件坏事,尤其是在它已经加载的情况下,在这种情况下你会得到一个异常。如果您确定它是同一个程序集,请使用 Activator.CreateInstance。如果没有,在加载的程序集中搜索类型。
      • 程序集已被引用并且命名空间已被导入。有没有办法做到这一点而不必再次加载程序集?
      猜你喜欢
      • 1970-01-01
      • 2011-06-02
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-30
      相关资源
      最近更新 更多