簡體   English   中英

使用反射在方法調用上獲取正確的返回值

[英]Getting correct return value on a method call using reflection

我的類中有以下泛型方法作為存儲庫模式:

public DbSet<T> GetAll<T>() where T : class
{
  return dbContext.Set<T>();
}

現在,我想獲得數據庫中屬於實現特定接口( IChangeTrackingEntity )的實體類的所有實體的列表。 所以目前大約有10個特定的表/類符合這一點,但是我不想為這些表添加10個硬編碼調用,所以我想用反射來代替(也可能是實現的類)這個界面將來會發生變化,我也不想記得在這里改變並使代碼相互依賴)。

有效的代碼示例,但我不想要:

var result = new List<IChangeTrackingEntity>();
using ( var repository = new DbRepository())
{
  result.AddRange( repository.GetAll<FirstTypeThatImplementsInterface>() );
  result.AddRange( repository.GetAll<SecondTypeThatImplementsInterface>() );
  result.AddRange( repository.GetAll<ThirdTypeThatImplementsInterface>() );
  result.AddRange( repository.GetAll<FourthTypeThatImplementsInterface>() );
  result.AddRange( repository.GetAll<FifthTypeThatImplementsInterface>() );
}
return result;

我非常接近,但是我無法將最后一部分用於將Invoke的結果轉換回正確的類型。 我現在得到的是這個:

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

上面的問題是Invoke調用返回一個object ,我需要將它DbSet<pType>

在我當前的代碼genericMethod.Invoke(repository, null) as DbSet<IChangeTrackingEntity>返回null表示我無法按照自己的意願轉換返回值,因此我需要特定的返回值類型而不是我認為的接口。

知道怎么做到這一點?

嘗試轉換為IEnumerable<IChangeTrackingEntity> 這應該由於共同/逆轉而起作用。

我對這個具體問題了解不多,但您似乎是從DbSet<T> where T : IChangeTrackingEntity進行投射, DbSet<T> where T : IChangeTrackingEntityDbSet<IChangeTrackingEntity> 這被稱為協方差或逆變(我總是在它們之間混淆......)它只有在DbSet<>是一個接口時才有效。 所以,鑄造在這里不起作用。 如果可以的話,使用等效的接口,或者創建一個接受DbSet的泛型方法,其中T: IChangeTrackingEntity並以某種方式返回DbSet<IChangeTrackingEntity> 如果沒有人在我面前回答,我會嘗試找出如何做到這一點並發布答案(不太可能在本網站上發布:P)

我想你需要看到這個問題

MethodInfo method = typeof(Sample).GetMethod("GenericMethod");
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(this, null);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM