假设我有一些界面如下所示
public interface IPerson
{
Person GetPerson(string name);
Person SetPerson(Person p);
}
我的person对象有一些嵌套对象,也许它继承自基类。
public class Person : SomeBaseClass
{
public Name fullName {get;set;}
// some other stuff
}
现在让我们说以上所有内容都编译成程序集(dll)。是否可以使用反射动态实例化Person对象?
void Main()
{
Type type = typeof(IPerson);
var instance = Activator.CreateInstace(t);
// can't access properties of Person from instance.. :(
// I wan't to populate all the properties of the object on the fly
// but can't
}
基本上我想引用dll或加载程序集动态迭代所述程序集中的所有对象,创建对象并填充它们的属性,最后对这些对象及其属性执行某些操作。这可能吗?似乎我在进行静态转换时只能访问Person.Name。
var oops = (Person)instance; // now I can access. but I dont want to have to cast!
答案 0 :(得分:2)
加载组件。加载程序集后,您可以执行以下操作:
foreach(var type in assembly.GetTypes())
{
//if the type implements IPerson, create it:
if(typeof(type).GetInterfaces().Contains(typeof(IPerson))
{
var person = (IPerson)activator.CreateInstance(type);
//now you can invoke IPerson methods on person
}
}
这将使用默认构造函数在程序集中创建实现IPerson的每个类型的实例。
答案 1 :(得分:1)
要创建类型化实例,您可以使用Activator.CreateInstance<T>()
。但是你需要传递一个具体的类型,而不是一个接口。所以,它应该是
Person instance = Activator.CreateInstance<Person>();
如果你仍然需要能够使用接口,你应该使用一些DI容器来首先将IPerson
接口映射到Person
类(可以通过反射完成),然后使用容器来解析IPerson
。
答案 2 :(得分:0)
根据您的问题,您不清楚您要创建的所有对象是否实现IPerson
。如果他们这样做,那么Joe Enzminger的回答将会很有效。如果他们没有全部实施IPerson
,您将不得不使用更多反射来获取属性集,找出每个属性的类型,然后采取行动。
var properties = instance.GetType().GetProperties();
foreach(var property in properties)
{
var propertyType = property.PropertyType;
if(propertyType == typeof(string))
{
property.SetValue(instance, "A String");
}
else if(propertyType == typeof(int))
{
property.SetValue(instance, 42);
}
// and so on for the different types
}