At runtime, I would like to specify a parent class, and then the program would generate a list of all children classes (of however many generations). For example, if I had
One possible way would utilize the Type.IsAssignableFrom
method. You would loop over all types, and select those for which it is true.
Basically, it would be something like
Type parent = Type.GetType("Entity");
Type[] types = Assembly.GetExecutingAssembly().GetTypes(); // Maybe select some other assembly here, depending on what you need
Type[] inheritingTypes = types.Where(t => parent.IsAssignableFrom(t));
I don't have a compiler available at this time, so I can't verify it, but it should be mostly correct
This is what I use to find all children of some class (can be also abstract class) in selected assembly:
public class InheritedFinder
{
public static Type[] FindInheritedTypes(
Type parentType, Assembly assembly)
{
Type[] allTypes = assembly.GetTypes();
ArrayList avTypesAL = new ArrayList();
return allTypes.Where(
t => parentType.IsAssignableFrom(t) && t != parentType).ToArray();
}
}
Simply call by
var availableTypes = InheritedFinder.FindInheritedTypes(
typeof(YourBaseClass),
System.Reflection.Assembly.GetExecutingAssembly());
This will give you list of available children of YourBaseClass. Nice thing about it - it'll find also children of children, so you can use multi-level abstract classes. If you need to create instances of every child, easy:
var availableTypes= InheritedFinder.FindInheritedTypes(
typeof(Shape), System.Reflection.Assembly.GetExecutingAssembly());
foreach (var t in availableTypes)
{
try
{
YourBaseClass nInstance = (YourBaseClass)Activator.CreateInstance(t);
//nInstance is now real instance of some children
}
catch (Exception e)
{
//recommended to keep here - it'll catch exception in case some class is abstract (=can't create its instance)
}
}
var pType = typeof(Entity);
IEnumerable<string> children = Enumerable.Range(1, iterations)
.SelectMany(i => Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && t != pType
&& pType.IsAssignableFrom(t))
.Select(t => t.Name));
Demo