Get all inherited classes of an abstract class [duplicate]
Solution 1:
This is such a common problem, especially in GUI applications, that I'm surprised there isn't a BCL class to do this out of the box. Here's how I do it.
public static class ReflectiveEnumerator
{
static ReflectiveEnumerator() { }
public static IEnumerable<T> GetEnumerableOfType<T>(params object[] constructorArgs) where T : class, IComparable<T>
{
List<T> objects = new List<T>();
foreach (Type type in
Assembly.GetAssembly(typeof(T)).GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T))))
{
objects.Add((T)Activator.CreateInstance(type, constructorArgs));
}
objects.Sort();
return objects;
}
}
A few notes:
- Don't worry about the "cost" of this operation - you're only going to be doing it once (hopefully) and even then it's not as slow as you'd think.
- You need to use
Assembly.GetAssembly(typeof(T))
because your base class might be in a different assembly. - You need to use the criteria
type.IsClass
and!type.IsAbstract
because it'll throw an exception if you try to instantiate an interface or abstract class. - I like forcing the enumerated classes to implement
IComparable
so that they can be sorted. - Your child classes must have identical constructor signatures, otherwise it'll throw an exception. This typically isn't a problem for me.
Solution 2:
Assuming they are all defined in the same assembly, you can do:
IEnumerable<AbstractDataExport> exporters = typeof(AbstractDataExport)
.Assembly.GetTypes()
.Where(t => t.IsSubclassOf(typeof(AbstractDataExport)) && !t.IsAbstract)
.Select(t => (AbstractDataExport)Activator.CreateInstance(t));
Solution 3:
It may not be the elegant way but you can iterate all classes in the assembly and invoke Type.IsSubclassOf(AbstractDataExport)
for each one.