2011-11-21 245 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