如何在程序集中查找从特定类型C#继承的所有类型


Answers:


150

就像是:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
    return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}

如果您需要处理泛型,那会有些棘手(例如,传入开放List<>类型,但希望取回派生自的类型List<int>)。否则虽然很简单:)

如果要排除类型本身,则可以很容易地做到这一点:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
    return assembly.GetTypes().Where(t => t != baseType && 
                                          baseType.IsAssignableFrom(t));
}

请注意,这还将允许您指定接口并找到实现该接口的所有类型,而不仅仅是像使用类那样Type.IsSubclassOf


2
谢谢!我最终使用了此谢谢-我最终使用了此公共静态List <Type> GetAllSubclassesOf(Type baseType){return Assembly.GetAssembly(baseType).GetTypes()。其中(type => type.IsSubclassOf(baseType))。ToList(); }
aceinthehole

@Downvoter在这里。我的评论不见了。如aceinthehole所示,答案不正确。我添加了正确的答案,因为我错过了ace注释,直到发现代码不起作用为止。圣诞节快乐。
Tim Murphy 2010年

@Tim:这是不正确的,它略有不同。IsAssignableFrom应该也可以。特别是我的版本也可以处理接口。你测试我的代码了吗?我的答案在什么情况下失败?
乔恩·斯基特

1
@乔恩 您的方法完全正确地处理接口。我是VB程序员,我们继承了类并实现了接口。这在C#中有所不同吗?我之所以问是因为,根据我的要求,这个问题想要继承类型的类型而不实现类型。
Tim Murphy

2
@Tim:在C#中,我们只对两者使用“:”,但是我通常会将接口视为类型的继承层次结构的一部分。
乔恩·斯基特

27

以下方法将获取继承一个类型的类型的集合。

C#

public IEnumerable<Type> FindSubClassesOf<TBaseType>()
{   
    var baseType = typeof(TBaseType);
    var assembly = baseType.Assembly;

    return assembly.GetTypes().Where(t => t.IsSubclassOf(baseType));
}

VB.NET

Public Function FindSubClasses(Of TBaseType)() As IEnumerable(Of Type)

    Dim baseType = GetType(TBaseType)
    Dim assembly = baseType.Assembly

    Return From t In assembly.GetTypes() 
           Where t.IsSubClassOf(baseType) 
           Select t

End Function

如果您需要包括实现接口的类型,请参见@Jon Skeet的答案。



1

考虑使用此方法(为PCL编写):

public IEnumerable<Type> FindDerivedTypes( Assembly assembly, Type baseType )
{
        TypeInfo baseTypeInfo = baseType.GetTypeInfo();
        bool isClass = baseTypeInfo.IsClass, isInterface = baseTypeInfo.IsInterface;

        return
            from type in assembly.DefinedTypes
            where isClass ? type.IsSubclassOf( baseType ) :
                  isInterface ? type.ImplementedInterfaces.Contains( baseTypeInfo.AsType() ) : false
            select type.AsType();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.