【问题标题】:How to find a Derived Class of a Generic Base Class when you only know the type of the Generic Base Class?只知道泛型基类的类型,如何找到泛型基类的派生类?
【发布时间】:2014-03-14 12:54:12
【问题描述】:

只知道泛型基类的类型,如何找到泛型基类的派生类?

我尝试了以下方法,但没有编译:

private Type FindRepositoryType(Type entityType)
{
    var repoTypes = Assembly.GetExecutingAssembly().GetTypes()
                            .Where(t => t.BaseType != null
                                && t.BaseType.IsGenericType
                                && t.BaseType.GetGenericTypeDefinition() == typeof(BaseRepository<entityType>))
                            .ToList();
    return null;
}

var repoType = FindRepositoryType(typeof(Product));

我希望找到 ProductRepository 类型:

public class ProductRepository : BaseRepository<Product>
{

}

【问题讨论】:

  • 你想使用基类获取基类的派生类,是吗?
  • 不,使用基类泛型类型,T。

标签: c# .net generics reflection types


【解决方案1】:

将您的 Where 子句替换为:

.Where(t => t.BaseType != null
         && t.BaseType.IsGenericType
         && t.BaseType.GetGenericTypeDefinition() == typeof (BaseRepository<>)
         && t.BaseType.GetGenericArguments().Single() == entityType)

【讨论】:

  • GenericTypeArguments 在哪里?我正在使用 .NET 4.0,它不存在。
  • @TheLight 对不起,在编辑之前误解了你的问题 - 我已经编辑使其与 4.0 兼容。
【解决方案2】:

其他答案(也不依赖于 .NET 4.5 GenericTypeArguments 属性)的稍短的替代方案可能是:

// Create a type that represents `BaseRepository` with `entityType` as the generic parameter
var expectedType = typeof(BaseRepository<>).MakeGenericType(entityType);
// verify that it actually exists in the current assembly (will throw if it doesn't)
return Assembly.GetExecutingAssembly().GetTypes().Single(p => p.BaseType == expectedType);

【讨论】:

    【解决方案3】:

    你离得不远了。

    GetGenericTypeDefinition 将返回没有任何类型参数的泛型类型。在您的情况下,这将是BaseRepository&lt;&gt;(注意空括号)。如果你也想匹配泛型类型参数,你也需要使用GetGenericArguments。所以你的支票是这样的:

    t.BaseType.GetGenericTypeDefinition() == typeof(BaseRepository<>) && 
    t.BaseType.GetGenericArguments()[0] == entityType
    

    虽然GetGenericArguments() 返回一个类型数组,但您可以肯定会有一个,因为您之前确保泛型类型定义是BaseRepository&lt;&gt;,它恰好有一个类型参数.

    最后,你还想返回你找到的类型,而不是null

    private Type FindRepositoryType (Type entityType)
    {
        return Assembly.GetExecutingAssembly().GetTypes()
            .Where(t => t.BaseType != null
                && t.BaseType.IsGenericType
                && t.BaseType.GetGenericTypeDefinition() == typeof(BaseRepository<>)
                && t.BaseType.GetGenericArguments()[0] == entityType)
            .FirstOrDefault();
    }
    

    【讨论】:

      猜你喜欢
      • 2014-03-22
      • 2012-09-08
      • 1970-01-01
      • 2018-01-13
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多