Bunun çok eski bir soru olduğunu takdir ediyorum ama bugüne kadarki tüm cevaplar bir tür kullandığından gelecekteki kullanıcılar için başka bir cevap ekleyeceğimi düşündüm Assembly.GetTypes
.
GetTypes () gerçekten tüm türleri döndürecek olsa da, onları etkinleştirebileceğiniz ve dolayısıyla potansiyel olarak a atabileceğiniz anlamına gelmez ReflectionTypeLoadException
.
Bir türü etkinleştirememenin klasik bir örneği, döndürülen türün , çağrı derlemesinin başvuruda bulunmadığı bir derlemeden farklı olduğu derived
, base
ancak bu türden base
farklı bir derlemede tanımlandığı durumdur derived
.
Diyelim ki elimizde:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
İçinde ClassC
ise, AssemblyC
kabul edilen cevaba göre bir şey yaparız:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
Sonra a atacak ReflectionTypeLoadException
.
Bunun nedeni için bir referans olmadan AssemblyA
içinde AssemblyC
size mümkün olmaz:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
Başka bir deyişle ClassB
değil yüklenebilir GetTypes çek çağrısı ve üzerinde atar şeydir.
Yüklenebilir türler için sonuç kümesini güvenli bir şekilde nitelendirmek için, bu Phil Haacked makalesine göre Bir Montajdaki Tüm Türleri Al ve Jon Skeet koduna göre şöyle bir şey yaparsınız:
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);
}
}
}
Ve sonra:
private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
var it = typeof (IMyInterface);
return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}