![](/img/trans.png)
[英]Create instance of class with generic type and call method of same generic type from string name of object at runtime
[英]create a generic class for the type name
有一個課
public class Repository <TKey, TEntity>
{
public ICollection<TEntity> Get()
{
using (var session = NHibernateHelper.OpenSession())
{
if (typeof(TEntity).IsAssignableFrom(typeof(IActualizable)))
return session.CreateCriteria(typeof(TEntity)).Add(Restrictions.Lt("ActiveTo", DBService.GetServerTime())).List<TEntity>();
return session.CreateCriteria(typeof(TEntity)).List<TEntity>();
}
}
}
如何創建它,僅知道TEntity的名稱?
例:
游戲類{}
字符串nameEntity =“ Game”;
var repository = new Repository <long, ??? >();
這包括三個部分:
"Game"
獲取Type
假設您了解更多,第一個相對容易-例如, Game
在特定的程序集和名稱空間中。 如果您知道該程序集中的某些固定類型,則可以使用:
Type type = typeof(SomeKnownType).Assembly
.GetType("The.Namespace." + nameEntity);
(並檢查它是否不返回null
)
然后我們需要創建泛型類型:
object repo = Activator.CreateInstance(
typeof(Repository<,>).MakeGenericType(new[] {typeof(long), type}));
但是,請注意,這是object
。 如果存在可用於Repository<,>
的非泛型接口或基類,這將更加方便-我會認真地添加一個!
要使用它,這里最簡單的方法是dynamic
:
dynamic dynamicRepo = repo;
IList entities = dynamicRepo.Get();
並使用非通用的IList
API。 如果不能選擇dynamic
則必須使用反射。
另外,添加一個非通用的API將使這個瑣碎的事情:
interface IRepository {
IList Get();
}
public class Repository <TKey, TEntity> : IRepository {
IList IRepository.Get() {
return Get();
}
// your existing code here
}
那就是:
var repo = (IRepository)Activator.CreateInstance(
typeof(Repository<,>).MakeGenericType(new[] {typeof(long), type}));
IList entities = repo.Get();
注意:根據數據, IList
可能不起作用-您可能需要改為使用非通用IEnumerable
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.