schließt man I schätzen dies eine sehr alte Frage, aber ich dachte, dass ich eine andere Antwort für zukünftige Benutzer, da alle Antworten auf Datum hinzufügen würde in irgendeiner Form verwenden von Assembly.GetTypes
.
Während GetTypes() in der Tat alle Typen zurückgibt, bedeutet es nicht unbedingt, dass Sie sie aktivieren könnten und somit möglicherweise eine ReflectionTypeLoadException
werfen könnten.
Ein klassisches Beispiel für keinen Typen zu aktivieren in der Lage wäre, wenn die zurück Typ derived
von base
aber base
ist in einer anderen Baugruppe von den derived
, eine Baugruppe definiert, dass die anrufende Assembly verweist nicht.
So sagen wir:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
Wenn in ClassC
, die in AssemblyC
ist, dass wir dann etwas tun, wie pro akzeptierte Antwort:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
Dann wird es einen ReflectionTypeLoadException
werfen.
Dies liegt daran, ohne Verweis auf AssemblyA
in AssemblyC
würden Sie nicht in der Lage sein:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
Mit anderen Worten ClassB
ist nicht ladbaren die etwas, das der Aufruf von GetTypes Kontrollen und wirft.
Also, um sicher die Ergebnismenge für ladbare Typen zu qualifizieren dann nach dieser Phil Haacked Artikel Get All Types in an Assembly und Jon Skeet code Sie stattdessen etwas tun würde, wie:
public static class TypeLoaderExtensions {
public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly) {
if (assembly == null) throw new ArgumentNullException("assembly");
try {
return assembly.GetTypes();
} catch (ReflectionTypeLoadException e) {
return e.Types.Where(t => t != null);
}
}
}
Und dann:
private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
var it = typeof (IMyInterface);
return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}
Funktioniert der Beispielcode?Ich habe falsche Negative mit Ihrer if-Bedingung. –
Die if-Anweisung im obigen Code wird immer falsch sein, weil Sie testen, ob eine Instanz der Type-Klasse (t) Ihre Schnittstelle implementiert. Dies geschieht nur, wenn Type IMyInterface erbt (in diesem Fall wird es immer wahr). – Liazy