[英]difference between Activator.CreateInstance and Activator.CreateInstance<Type>
[英]Activator.CreateInstance with dynamic Type
我认为我缺乏理解,究竟发生了什么:用户可以输入程序集的路径和对象类型,我尝试创建它的实例。
我的方法:
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进行威胁。 在这个例子中: 从类型创建泛型变量 - 如何? 或者使用带有属性{}而不是参数()的Activator.CreateInstance()?
他们只是得到一个对象,所以我猜这不是同一个案例。 我根本不理解:CreateInstance(Type)可以工作,但是Type的CreateInstance没有,但是T和Type应该是相同的:System.Type。
在此先感谢您的澄清。
马蒂亚斯
有一个使用差异...当你写:
var obj = Activator.CreateInstance<myType>();
您使用类似类型的类,这是实现它的好方法。 您使用了具有类类型引用的泛型类型。
但那里:
var obj2 =(myType) Activator.CreateInstance(myType);
你使用类就像一个实例(对象)。 你不能这样做,一个类是一个模式。 如果要调用第二种方法,则必须编写:
var obj2 =(myType) Activator.CreateInstance(typeof(myType));
此代码将创建类Type的实例,此实例将描述您的类myType。
我希望能够清楚。
类是一个模式,您可以使用此模式创建一个对象,它将是一个实例(您的类的内存对象)。
当您使用泛型类型的方法,如Activator.CreateInstance<T>();
你必须提供强类型的T.这意味着你必须传递已知的类型名称而不是T.例如:
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);
因为您必须为显式转换提供强类型名称。 当我们在运行时无法访问强类型名称时,我们必须使用非泛型版本的方法。
这是纯粹的动态方式。
这是工厂类和动态实例创建方法:
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;
}
}
这是在Entity和Repository之间映射类型的帮助器类。
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 :)
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.