2011-11-21 142 views
3

给出一个泛型类型约束的所有可能的排列:反映了泛型类型约束

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<>),我会得到上面的类型。

回答

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

想法,如果你给出的只是'MyClass'类型? –

+0

已更新,因此运行时类型的alpha不是必需的。 –

+0

@AustinSalonen回答现在更新完成解决方案(假设所有必需的程序集已加载)。 –

0

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