有没有办法根据我在运行时知道类的名称这一事实来创建类的实例。基本上我会在一个字符串中包含类的名称。
8 回答
看一下Activator.CreateInstance方法。
它很简单。假设您的类名是Car
并且命名空间是Vehicles
,然后将参数作为Vehicles.Car
返回类型的对象传递Car
。像这样,您可以动态创建任何类的任何实例。
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
如果您的完全限定名称(即,Vehicles.Car
在这种情况下)在另一个程序集中,则Type.GetType
将为空。在这种情况下,您需要遍历所有程序集并找到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;
}
现在,如果您想调用参数化构造函数,请执行以下操作
Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
代替
Activator.CreateInstance(t);
我已经成功地使用了这个方法:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
您需要将返回的对象转换为所需的对象类型。
可能我的问题应该更具体。我实际上知道字符串的基类,因此通过以下方式解决了它:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Activator.CreateInstance 类有多种方法以不同的方式实现相同的事情。我本可以将它投射到一个对象上,但以上对我的情况最有用。
要从解决方案中的另一个项目创建类的实例,您可以获取由任何类的名称(例如 BaseEntity)指示的程序集并创建一个新实例:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
我知道我迟到了……但您正在寻找的解决方案可能是上述的组合,并使用接口来定义您的对象可公开访问的方面。
然后,如果以这种方式生成的所有类都实现了该接口,则可以将其强制转换为接口类型并使用生成的对象。
例如,如果您将各种类型的值存储在数据库字段中(存储为字符串),并有另一个字段类型名称为(即 String、bool、int、MyClass),那么从该字段数据中,您可以想象,使用上面的代码创建一个任意类型的类,并用第一个字段中的值填充它。这当然取决于您存储的类型是否有将字符串解析为正确类型的方法。我已经多次使用它来将用户首选项设置存储在数据库中。
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
你为什么要写这样的代码?如果你有一个类'ReportClass'可用,你可以直接实例化它,如下所示。
ReportClass report = new ReportClass();
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
当您没有必要的类可用时使用该代码,但您想动态地实例化和/或调用方法。
我的意思是当你知道程序集但在编写代码时你没有可用的类时它很有ReportClass
用。