2010-03-02 3 views

ответ

34

в значительной степени так же, как Дарин, но здесь вы идете ..

public static List<Type> FindAllDerivedTypes<T>() 
    { 
     return FindAllDerivedTypes<T>(Assembly.GetAssembly(typeof(T))); 
    } 

    public static List<Type> FindAllDerivedTypes<T>(Assembly assembly) 
    { 
     var derivedType = typeof(T); 
     return assembly 
      .GetTypes() 
      .Where(t => 
       t != derivedType && 
       derivedType.IsAssignableFrom(t) 
       ).ToList(); 

    } 

используется как:

var output = FindAllDerivedTypes<System.IO.Stream>(); 
      foreach (var type in output) 
      { 
       Console.WriteLine(type.Name); 
      } 

выходов:

NullStream 
SyncStream 
__ConsoleStream 
BufferedStream 
FileStream 
MemoryStream 
UnmanagedMemoryStream 
PinnedBufferMemoryStream 
UnmanagedMemoryStreamWrapper 
IsolatedStorageFileStream 
CryptoStream 
TailStream 
+0

Я предполагаю, что вы используете 'IsAssignableFrom' вместо' IsSubclassOf' для учета интерфейсов. Но вызов этого интерфейса также возвращает его реализующие классы. – HappyNomad

11
var types = Assembly 
    .GetExecutingAssembly() 
    .GetTypes() 
    .Where(t => typeof(SomeBaseType).IsAssignableFrom(t) && 
       t != typeof(SomeBaseType)) 
    .ToArray(); 
28
var derivedTypes = from t in Assembly.GetExecutingAssembly().GetTypes() 
        where t.IsSubclassOf(typeof(A)) 
        select t; 
+0

Это стоит отметить, этот запрос извлекает только интерфейсы или классы, которые непосредственно вытекают из типа 'Ā'. – ZenLulz

+0

@ ZenLulz Недопустимое значение параметра ['IsSubclassOf'] (https://msdn.microsoft.com/en-us/library/system.type.issubclassof.aspx). Фактически, он возвращает 'true' для * производных классов *. – HappyNomad

3

я переписал @ отличный ответ Имеющий в качестве метода расширения:

public static class TypeExtensions 
{ 
    public static List<Type> GetAllDerivedTypes(this Type type) 
    { 
     return Assembly.GetAssembly(type).GetAllDerivedTypes(type); 
    } 

    public static List<Type> GetAllDerivedTypes(this Assembly assembly, Type type) 
    { 
     return assembly 
      .GetTypes() 
      .Where(t => t != type && type.IsAssignableFrom(t)) 
      .ToList(); 
    } 
} 

Использование:

var listOfDerived = typeof(MyClass).GetAllDerivedTypes(); 
+1

Зачем использовать ['IsAssignableFrom'] (https://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx) вместо [' IsSubclassOf'] (https://msdn.microsoft.com /en-us/library/system.type.issubclassof.aspx)? Может быть, вы хотите поддерживать интерфейсы? Но этот результат будет включать в себя реализацию классов. – HappyNomad

+0

@HappyNomad Вы делаете отличную оценку. В моем случае я хотел поддерживать интерфейсы. –

+0

Мой [ответ] (http://stackoverflow.com/a/40238277) для дублирующего вопроса поддерживает интерфейсы. – HappyNomad