反映具有约束的泛型类型的所有可能排列

时间:2011-11-21 22:57:03

标签: c# generics reflection

给定具有约束的泛型类型:

class MyClass<T> where T: Alpha
{
}

和该约束的实现:

class Alpha {}
class Bravo : Alpha {}
class Charlie : Alpha {}

如何在运行时获取所有组合的泛型类型?

// I want these types at run-time
MyClass<Alpha> 
MyClass<Bravo> 
MyClass<Charlie> 

编辑:根据@ rich.okelly的回答,我认为真正的问题是:

如何在运行时找到实现我的泛型类型约束的所有类型?

因此,如果我获得typeof(MyClass<>),我会得到上面的类型。

2 个答案:

答案 0 :(得分:4)

类似的东西:

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);
}

或者,如果已经加载了泛型类型:

var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(MyClass<>));
foreach (var type in allTypes) 
{
  ...
}

更新

您可以使用the GetGenericArguments() methodthe GetGenericParameterConstraints() method来获取所需类型。

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)
{
    ...
}

答案 1 :(得分:0)

您可以枚举应用程序域中所有已加载的程序集。然后枚举每个Assembly中的所有类型并测试每个类型是否为常量的subclass