我认为我缺乏理解,到底发生了什么: 用户可以输入程序集的路径和对象类型,然后尝试创建它的实例。
我的方法:
Assembly a = Assembly.LoadFile(txtAssemblyPath.Text);
Type myType = a.GetTypes().ToList().FirstOrDefault(f => f.Name == txtObjectName.Text);
var obj = Activator.CreateInstance<myType>();
var obj2 =(myType) Activator.CreateInstance(myType);
问题在于创建对象本身。似乎myType没有作为Type进行威胁。在此示例中:Creating generic variables from a type - How? Or use Activator.CreateInstance() with properties { } instead of parameters ( )?
他们只是得到一个对象,所以我猜这不是同一个案例。我根本不理解:CreateInstance(Type)有效,但Type的CreateInstance没有,但T和Type应该相同:System.Type。
提前感谢澄清。
的Matthias
答案 0 :(得分:3)
有一个使用差异......当你写:
var obj = Activator.CreateInstance<myType>();
你像班级一样使用你的班级,这是做这件事的好方法。 您使用了一个引用类类型的泛型类型。
但是那里:
var obj2 =(myType) Activator.CreateInstance(myType);
您使用的类就像一个实例(对象)。你不能这样做,一个类是一个模式。 如果要调用第二种方法,则必须写:
var obj2 =(myType) Activator.CreateInstance(typeof(myType));
此代码将创建类Type的实例,此实例将描述您的类myType。
我希望能够清楚。
一个类是一个模式,你可以用这个模式创建一个对象,它将是一个实例(你的类的一个内存对象)。
答案 1 :(得分:2)
当您使用泛型类型的方法(例如Activator.CreateInstance<T>();
)时,您必须提供T的强类型。这意味着您必须传递已知类型名称而不是T.例如:< / p>
var activatorPerson = (Person)Activator.CreateInstance<Person>();
这就是Activator.CreateInstance(typeGoesHere)
函数的非泛型的原因,可用于我们没有强类型的情况在创建对象的那一刻。所以我们可以将type作为参数传递给该函数。我们可以通过多种方式提供类型变量。在您的情况下,您可以在程序集中找到正确的类型:
Type myType = a.GetTypes().ToList().FirstOrDefault(f => f.Name == txtObjectName.Text);
您还必须注意,在您的代码中键入的显式转换无效:
obj2 =(myType) Activator.CreateInstance(myType);
因为您必须为显式转换提供强类型名称。 当我们在运行时无法访问强类型名称时,我们必须使用非泛型版本的方法。
答案 2 :(得分:0)
这是纯粹的动态方式。
这是工厂类和动态实例创建方法:
public class RepositoryFactory
{
public static dynamic CreateDynamic<TEntity>() where TEntity : BaseEntity
{
dynamic repositoryInstance = null;
var subRepositories = AssemblyHelper.GetSubclassesOf(typeof(BaseRepository<TEntity>), true);
var entityTypeName = typeof(TEntity).Name;
var subRepository = subRepositories.FirstOrDefault(x => x.Name == entityTypeName + "Repository");
if (subRepository != null)
{
var repositoryType = subRepository.UnderlyingSystemType;
repositoryInstance = Activator.CreateInstance(repositoryType);
}
return repositoryInstance;
}
}
这是实体和存储库之间映射类型的辅助类。
public static class AssemblyHelper
{
public static List<Type> GetSubclassesOf(Type type, bool ignoreSystem)
{
List<Type> lReturn = new List<Type>();
foreach (var a in System.Threading.Thread.GetDomain().GetAssemblies())
{
if (ignoreSystem && a.FullName.StartsWith("System."))
{
continue;
}
foreach (var t in a.GetTypes())
{
if (t.IsSubclassOf(type) || (type.IsInterface && t.GetInterfaces().FirstOrDefault(e => e.FullName == type.FullName) != null))
{
lReturn.Add(t);
}
}
}
return lReturn;
}
}
这是用例的Manager类:
public class PageManager
{
private readonly ContentPageRepository _pageRepository;
public PageManager()
{
_pageRepository = RepositoryFactory.CreateDynamic<ContentPage>();
}
public void GetPagesByContentType(ContentType type)
{
var pages = _pageRepository.GetByPredicate(x => x.Status != EntityStatus.Deleted && x.Node.Type == type);
foreach (var page in pages)
{
//Deal with it :)
}
}
}