调用通用 class 嵌套函数
Make call to generic class nested function
我有 Repository<T>
,其中 T
是 BaseEntity
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>
,其中 X
是 T
,属性 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));
}
我有 Repository<T>
,其中 T
是 BaseEntity
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>
,其中 X
是 T
,属性 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));
}