[英]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.