Given a generic type with constraints:
class MyClass<T> where T: Alpha
{
}
and implementations of that constraint:
class Alpha {}
class Bravo : Alpha {}
class Charlie : Alpha {}
How can get generic types for all the combinations at run-time?
// I want these types at run-time
MyClass<Alpha>
MyClass<Bravo>
MyClass<Charlie>
EDIT: Based on @rich.okelly's answer, I think the real question is this:
How can I find all the types that implement my generic type's constraint at run-time?
So if I'm given typeof(MyClass<>)
, I get the types above.
Something like:
var alphaType = typeof(Alpha);
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => alphaType.IsAssignableFrom(t));
var myClass = typeof(MyClass<>);
foreach (var type in allTypes)
{
var genericType = myClass.MakeGenericType(type);
}
Alternatively, if the generic types have already been loaded:
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(MyClass<>));
foreach (var type in allTypes)
{
...
}
Update
You can use the GetGenericArguments()
method and the GetGenericParameterConstraints()
method to get the required types.
var myType = typeof(MyClass<>);
var typeConstraints = myType.GetGenericArguments().First().GetGenericParameterConstraints();
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes());
var genericTypes = allTypes.Where(t => typeConstraints.All(tc => tc.IsAssignableFrom(t))).Select(t => myType.MakeGenericType(t));
foreach (var type in genericTypes)
{
...
}
You can enumerate all loaded assemblies in the app domain. And then enumerate all the types in each Assembly and test to see if each type is a subclass of the constant.