调用泛型类嵌套函数

时间:2017-12-11 06:48:58

标签: c# entity-framework generics reflection system.reflection

Repository<T>其中T来自BaseEntity类。 Repository<T>具有IQueryable<T> Table属性。我需要调用FirstOrDefault属性中的Table方法。

到现在为止我必须列出存储库,但是仍然使用反射来调用方法。

private IEnumerable<object> GetEnumerableRepositoryOf<T>(params object[] constructorArgs) where T : class
        {
            List<object> objects = new List<object>();
            foreach (Type type in
                Assembly.GetAssembly(typeof(T)).GetTypes()
                .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T))))
            {                
                objects.Add(Activator.CreateInstance(typeof(Repository<>).MakeGenericType(type), constructorArgs));
            }
            return objects;
        }

var repoList = GetEnumerableRepositoryOf<BaseEntity>(constructorArgs);
foreach (var repo in repoList)
        {               
            // call FirstOrDefault() here
        }

1 个答案:

答案 0 :(得分:1)

因此,您的列表为Repository<X>,其中XT,属性表为IQueryable<X>。由于我们在编译时缺乏X的类型知识,因此反思它。

因此,使用非泛型接口获取具有反射的属性,然后将强制转换应用于T,并执行FirstOrDefault。

以下是如何做到的:

foreach (var repo in repoList)
{
  var firstOrNull = 
    (repo.GetType().GetProperty("Table").GetValue(repo) as IQueryable)
      .Cast<BaseEntity>().FirstOrDefault();
}

如果使用实体框架(上面不支持这种转换):

foreach (var repo in repoList)
{
  var enumerator = 
    (repo.GetType().GetProperty("Table").GetValue(repo) as IEnumerable)
      .GetEnumerator();

  var firstOrNull = (BaseEntity) (enumerator.MoveNext() ? 
        enumerator.Current : default(BaseEntity));
}