根据给定的类型实现泛型方法调用

Achieve generic method invocation depending on the type given

我有一些(非)通用函数明确分配给 DbSet(使用 Entity Framework 6.1,但从某种意义上说,这个问题更通用):

//Non-generic type method
public static IQueryable BuildQuery(this DbSet dbSet)
{
  return dbSet;
}
//Generic base class elements method
public static IQueryable<Entity> BuildQuery(this DbSet<Entity> dbSet)
{
  return dbSet.Include(de1 => de1.NavigationPropertyBase);
}
//Derived class 1 elements method
public static IQueryable<DerivedEntity1> BuildQuery(this DbSet<DerivedEntity1> dbSet)
{
  return dbSet.Include(de1 => de1.NavigationPropertyX);
}
//Derived class 2 elements method
public static IQueryable<DerivedEntity2> BuildQuery(this DbSet<DerivedEntity2> dbSet)
{
  return dbSet.Include(de2 => de2.NavigationPropertyX).
               Include(de2 => de2.NavigationPropertyY);
}

我知道虽然 DerivedEntity1DerivedEntity2 扩展了 Entity,但 Dbset<DerivedEntityX> 没有扩展 DbSet<Entity>

不过,我想做的是基于通用类型实现 late-binding 类行为。我想将泛型类型放入一个非泛型变量中,然后调用 BuildQuery 方法(可见,因为它在编译时存在于非泛型类型中):

//This compiles with no errors.
DbSet dbSetNonGeneric = dbSet; // dbSet is of DbSet<DerivedEntity1> type
var result = dbSetNonGeneric.BuildQuery();

我的问题是,这会导致根据泛型调用BuildQuery方法还是会调用非泛型方法?而在第二种情况下,有没有办法实现那种方法调用?

will this lead to an invocation of the BuildQuery method according to the generic type or will it invoke the non-generic method?

它将使用非泛型重载。

And in the second case, is there a way to achieve that kind of method invocation?

您可以将变量键入 dynamic,但结果也将是 dynamic

您也可以使用反射来确定 dbSetNonGeneric 的类型、您要使用的重载,并在对象上调用该重载。

更新:由于动态查找无法找到扩展方法 (link),因此应将这些方法用作普通静态方法,以便与 dynamic.[=17= 结合使用]

它将调用非泛型方法。原因很简单,扩展方法调用基于变量类型而不是运行时类型(派生类型)

根据@Servy 的建议,您可以使用反射,但我对 dynamic 有疑问。

当您有扩展方法时,dynamic 关键字将不起作用。

要用反射调用,您必须做一些工作。实际上,当使用反射时,它不会成为实例方法的一部分,但它就像您用来创建扩展方法的静态 class 的静态方法。

以下link将帮助您获取该方法并使用反射进行调用。

Reflection to Identify Extension Methods