簡體   English   中英

為類型名稱創建一個通用類

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM