获取实现特定开放泛型类型的所有类型

时间:2011-12-27 13:57:43

标签: c# generics reflection open-generics

如何获得实现特定开放泛型类型的所有类型?

例如:

public interface IUserRepository : IRepository<User>

查找实施IRepository<>的所有类型。

public static IEnumerable<Type> GetAllTypesImplementingOpenGenericType(Type openGenericType, Assembly assembly)
{
  ...
}

4 个答案:

答案 0 :(得分:58)

这将返回继承通用基类的所有类型。并非所有继承通用接口的类型。

var AllTypesOfIRepository = from x in Assembly.GetAssembly(typeof(AnyTypeInTargetAssembly)).GetTypes()
 let y = x.BaseType
 where !x.IsAbstract && !x.IsInterface &&
 y != null && y.IsGenericType &&
 y.GetGenericTypeDefinition() == typeof(IRepository<>)
 select x;

这将返回所有类型,包括接口,摘要和在其继承链中具有开放泛型类型的具体类型。

public static IEnumerable<Type> GetAllTypesImplementingOpenGenericType(Type openGenericType, Assembly assembly)
{
    return from x in assembly.GetTypes()
            from z in x.GetInterfaces()
            let y = x.BaseType
            where
            (y != null && y.IsGenericType &&
            openGenericType.IsAssignableFrom(y.GetGenericTypeDefinition())) ||
            (z.IsGenericType &&
            openGenericType.IsAssignableFrom(z.GetGenericTypeDefinition()))
            select x;
}

在此示例中,第二种方法将找到 ConcreteUserRepo IUserRepository

public interface ConcreteUserRepo : IUserRepository
{}

public interface IUserRepository : IRepository<User>
{}

public interface IRepository<User>
{}

public class User
{}

答案 1 :(得分:4)

在没有LINQ的情况下实现的解决方案,搜索通用和非通用接口,将返回类型过滤到类。

Light Status :  1645.0(lux) 
CPU info     :  Usage: 82%  Temperature= 63~C
Battery Info :  Status= 100%  Temperature= 34.5~C

答案 2 :(得分:3)

你可以尝试

openGenericType.IsAssignableFrom(myType.GetGenericTypeDefinition()) 

myType.GetInterfaces().Any(i => i.GetGenericTypeDefinition() = openGenericType)

答案 3 :(得分:0)

您可以使用以下代码获取实现IRepository<>接口的所有类型:

List<Type> typesImplementingIRepository = new List<Type>();
IEnumerable<Type> allTypesInThisAssembly = Assembly.GetExecutingAssembly().GetTypes();

foreach (Type type in allTypesInThisAssembly)
{
    if (type.GetInterface(typeof(IRepository<>).Name.ToString()) != null)
    {
        typesImplementingIRepository.Add(type);
    }
}