Alle möglichen Permutationen eines generischen Typs mit Einschränkungen widerspiegeln

  • Für einen generischen Typ mit Einschränkungen gilt:

     class MyClass<T> where T: Alpha
    {
    }
     

    und Implementierungen dieser Einschränkung :

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

    Wie können generische Typen für alle Kombinationen zur Laufzeit abgerufen werden?

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

    BEARBEITEN: Basierend auf der Antwort von @ rich.okelly, denke ich, ist die eigentliche Frage diese: p>

    Wie kann ich alle Typen finden, die zur Laufzeit die Einschränkung meines generischen Typs implementieren?

    Wenn ich also typeof(MyClass<>) bekomme, bekomme ich die Typen oben.

    22 November 2011
    Austin Salonenuser1451939
2 answers
  • So etwas wie:

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

    Alternativ, wenn die generischen Typen bereits geladen wurden:

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

    Aktualisieren

    Sie kann die die Methode GetGenericArguments() und die Methode GetGenericParameterConstraints() , um die erforderlichen Typen abzurufen.

     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)
    {
        ...
    }
     
    22 November 2011
    Rich O'Kelly
  • Sie können alle geladenen Assemblys in der App-Domäne auflisten. Zählen Sie dann alle Typen in jeder Assembly auf und testen Sie, ob jeder Typ ein subclass der Konstanten.

    22 November 2011
    rerun