为类型名创建泛型类
本文关键字:泛型类 创建 类型 | 更新日期: 2023-09-27 18:19:21
有一个类
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的名字?
的例子:
类游戏{}
string nameEntity = "Game";
var repository = new repository <长,> ? ?> ();
这有三个部分:
- 从字符串
"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
。