从字符串创建类的实例

Pet*_*teT 198 .net c# instantiation system.type

有没有办法根据我在运行时知道类的名称来创建类的实例.基本上我会在字符串中有类的名称.

Mat*_*ton 150

看一下Activator.CreateInstance方法.

  • 与很好的例子相关:http://stackoverflow.com/questions/493490/converting-a-string-to-a-class-name (15认同)
  • 例如:`var driver =(OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver","OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();` (4认同)
  • 重要说明:.Unwrap()通过远程处理句柄,以便您可以实际进行转换.@Endy - 谢谢 (2认同)

Sar*_*avu 63

它非常简单.假设您的类名是Car和命名空间Vehicles,然后传递Vehicles.Car返回类型对象的参数Car.像这样,您可以动态创建任何类的任何实例.

public object GetInstance(string strFullyQualifiedName)
{         
     Type t = Type.GetType(strFullyQualifiedName); 
     return  Activator.CreateInstance(t);         
}
Run Code Online (Sandbox Code Playgroud)

如果您的完全限定名称(即,Vehicles.Car在这种情况下)在另一个程序集中,Type.GetType则将为null.在这种情况下,你循环遍历所有程序集并找到Type.为此,您可以使用以下代码

public object GetInstance(string strFullyQualifiedName)
{
     Type type = Type.GetType(strFullyQualifiedName);
     if (type != null)
         return Activator.CreateInstance(type);
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
     {
         type = asm.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
     }
     return null;
 }
Run Code Online (Sandbox Code Playgroud)

现在,如果要调用参数化构造函数,请执行以下操作

Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
Run Code Online (Sandbox Code Playgroud)

代替

Activator.CreateInstance(t);
Run Code Online (Sandbox Code Playgroud)

  • @TaW - 为了使用类实例,您需要了解它将要做什么 - 否则您将无法使用它。最常见的用例是转换到某个接口,为您提供预定义的合同。(除非您使用“动态”代码,否则这适用 - 请参阅 http://stackoverflow.com/a/2690661/904521) (2认同)
  • 不要在变量的名称中编码变量的类型。例如:不需要在“strFullyQualifiedName”前面加上“str”,“completelyQualifiedName”就可以完成这项工作。 (2认同)

Ray*_* Li 53

我成功地使用了这个方法:

System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Run Code Online (Sandbox Code Playgroud)

您需要将返回的对象强制转换为所需的对象类型.

  • 我明白你的意思了.这似乎是多余的.如果您知道类名,为什么需要动态字符串?一种情况可能是您对基类的转换和字符串表示该基类的后代. (12认同)
  • 我试图想象一个场景,通过类名创建对象然后将其转换为该类型将完全有意义. (8认同)
  • 如果已知基类,则可以使用基类或其接口作为参数来传递没有反射的后代. (3认同)
  • 有用的场景:您只需要序列化接口或任何其他非常常见的接口.你不会把它投射到课堂上,但至少要投射到一个以外的东西 (3认同)
  • 如何从给定的字符串中进行____的转换?? (2认同)

Pet*_*teT 22

可能我的问题应该更加具体.我实际上知道字符串的基类,所以解决了它:

ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Run Code Online (Sandbox Code Playgroud)

Activator.CreateInstance类有各种方法以不同的方式实现相同的功能.我可以将它投射到一个物体,但上面对我的情况最有用.

  • 我建议您编辑问题并记下更改,而不是在问题部分回复.你会得到更多/更好的答案. (3认同)

asd*_*asd 8

要从解决方案中的另一个项目创建类的实例,您可以获取由任何类的名称(例如 BaseEntity)指示的程序集并创建一个新实例:

  var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
Run Code Online (Sandbox Code Playgroud)