C# 使用反射获取方法调用的正确返回值
我的类中有以下作为存储库模式的通用方法:C# 使用反射获取方法调用的正确返回值,c#,generics,reflection,casting,C#,Generics,Reflection,Casting,我的类中有以下作为存储库模式的通用方法: public DbSet<T> GetAll<T>() where T : class { return dbContext.Set<T>(); } 我非常接近,但是我无法将调用的结果转换回正确的类型。我现在得到的是: var result = new List<IChangeTrackingEntity>(); var method = typeof (DbRepository).GetMethod
public DbSet<T> GetAll<T>() where T : class
{
return dbContext.Set<T>();
}
我非常接近,但是我无法将调用的结果转换回正确的类型。我现在得到的是:
var result = new List<IChangeTrackingEntity>();
var method = typeof (DbRepository).GetMethod("GetAll");
using ( var repository = new DbRepository())
{
foreach (var p in typeof(AnchorDbContext).GetProperties())
{
if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
{
var pType = p.PropertyType.GetGenericArguments()[0];
if (pType.GetInterface("IChangeTrackingEntity") != null)
{
var genericMethod = method.MakeGenericMethod(new[] {pType});
result.AddRange(genericMethod.Invoke(repository, null) as DbSet<IChangeTrackingEntity>);
}
}
}
return result;
}
var result=newlist();
var method=typeof(DbRepository).GetMethod(“GetAll”);
使用(var repository=new DbRepository())
{
foreach(typeof(AnchorDbContext.GetProperties())中的变量p)
{
if(p.PropertyType.IsGenericType&&p.PropertyType.GetGenericTypeDefinition()==typeof(DbSet))
{
var pType=p.PropertyType.GetGenericArguments()[0];
if(pType.GetInterface(“IChangeTrackingEntity”)!=null)
{
var genericMethod=method.MakeGenericMethod(new[]{pType});
AddRange(genericMethod.Invoke(repository,null)作为DbSet);
}
}
}
返回结果;
}
上面的问题是调用返回一个对象
,我需要将它转换为基本上DbSet
在我当前的代码genericMethod.Invoke(repository,null)中,DbSet
返回null
,这表明我无法按自己的意愿强制转换返回值,因此我需要的是特定的返回值类型,而不是我认为的接口
你知道如何做到这一点吗?我想你需要看看:
我对这个具体问题不太了解,但您似乎正在从DbSet进行转换,其中t:ichangetrackingenetity
到DbSet
。这称为协方差或逆方差(我总是混淆它们…),只有当DbSet
是一个接口时,它才起作用。所以,铸造在这里不起作用。如果可以,请使用等效接口,或者创建一个通用方法,该方法接受DbSet,其中T:IChangeTrackingEntity
并以某种方式返回DbSet
。如果在我之前没有人回答过(在这个网站上不太可能:P),我将尝试找出如何做到这一点,并发布一个答案。尝试转换到
IEnumerable
。这应该是可行的,因为co/相反。Hm您的代码对我来说没有意义。实现时,您将从数据库中获取与此接口匹配的所有实体。您知道这是一个性能问题吗?usr-是的,我想从数据库中获取所有这些条目,因为它们将被镜像到另一个数据库中,但不是数据库中的所有其他条目。问题不在于其中的参数,而在于我处理过的参数,而是返回类型。返回类型是DbSet,但我不知道如何进行转换。是的,我想这是一个协方差/反方差问题。foreach循环第一轮返回的实际列表是DbSet
,即使MobileUnit实现了IChangeTrackingEntity
,但协方差(或反方差,我把它们弄糊涂了:)并没有生效,并且强制转换被视为无效。似乎您的想法是正确的,usr证实了这一点。当我将其转换为IEnumerable而不是DbSet时,效果很好,因为协方差/逆变换开始生效。所以现在它成功了:D.也谢谢你的努力。我很高兴:)恐怕我不知道DbSet是什么:P成功了。看来我需要仔细阅读协方差/反方差。所以它在IEnumerable中工作是因为它是一个接口,但在DbSet上不是,因为它不是一个接口?谢谢你的努力。与界面无关。它对IEnumerable有效,因为您只能取出元素。DbSet允许您将内容放入其中,包括某个从IChangeTrackingEntity派生的随机类。这就是为什么它是不被允许的。但这不是因为协方差吗?我的意思是,我有继承B的类A。那么我不能设置DbSet=DbSet,但我可以设置IEnumerable=IEnumerable。若我能从IEnumerable中得到元素,那个又有什么关系呢?是的,这是由协方差引起的。我建议你读一读这个话题。这在实践中很少出现。
var result = new List<IChangeTrackingEntity>();
var method = typeof (DbRepository).GetMethod("GetAll");
using ( var repository = new DbRepository())
{
foreach (var p in typeof(AnchorDbContext).GetProperties())
{
if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
{
var pType = p.PropertyType.GetGenericArguments()[0];
if (pType.GetInterface("IChangeTrackingEntity") != null)
{
var genericMethod = method.MakeGenericMethod(new[] {pType});
result.AddRange(genericMethod.Invoke(repository, null) as DbSet<IChangeTrackingEntity>);
}
}
}
return result;
}
MethodInfo method = typeof(Sample).GetMethod("GenericMethod");
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(this, null);