调用通用 class 嵌套函数

Make call to generic class nested function

我有 Repository<T>,其中 TBaseEntity class 的派生形式。 Repository<T>IQueryable<T> Table 属性。我需要在 Table 属性.

中调用 FirstOrDefault 方法

直到现在我必须列出存储库,但仍然无法调用使用反射的方法。

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
        }

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

因此使用非通用接口通过反射获得 属性,然后将强制转换应用到 T,然后执行 FirstOrDefault。

你可以这样做:

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

如果使用entity framework(不支持上面的这种转换):

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));
}