Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用反射获取方法调用的正确返回值_C#_Generics_Reflection_Casting - Fatal编程技术网

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