Bagaimana Anda mendapatkan koleksi dari semua jenis yang mewarisi dari jenis tertentu lainnya?
Bagaimana Anda mendapatkan koleksi dari semua jenis yang mewarisi dari jenis tertentu lainnya?
Jawaban:
Sesuatu seperti:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}
Jika Anda perlu menangani generik, itu menjadi agak rumit (misalnya meneruskan List<>
tipe terbuka tetapi mengharapkan untuk mendapatkan kembali tipe yang diturunkan dari List<int>
). Kalau tidak, itu sederhana :)
Jika Anda ingin mengecualikan jenis itu sendiri, Anda dapat melakukannya dengan cukup mudah:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => t != baseType &&
baseType.IsAssignableFrom(t));
}
Perhatikan bahwa ini juga akan memungkinkan Anda untuk menentukan antarmuka dan menemukan semua tipe yang mengimplementasikannya, daripada hanya bekerja dengan kelas seperti Type.IsSubclassOf
halnya.
IsAssignableFrom
harus bekerja dengan baik. Secara khusus, versi saya juga menangani antarmuka. Apakah Anda menguji kode saya? Pada kasus apa jawaban saya gagal?
Metode berikut akan mendapatkan kumpulan tipe yang mewarisi tipe.
C #
public IEnumerable<Type> FindSubClassesOf<TBaseType>()
{
var baseType = typeof(TBaseType);
var assembly = baseType.Assembly;
return assembly.GetTypes().Where(t => t.IsSubclassOf(baseType));
}
VB.NET
Public Function FindSubClasses(Of TBaseType)() As IEnumerable(Of Type)
Dim baseType = GetType(TBaseType)
Dim assembly = baseType.Assembly
Return From t In assembly.GetTypes()
Where t.IsSubClassOf(baseType)
Select t
End Function
Jika Anda perlu menyertakan tipe yang mengimplementasikan antarmuka, lihat jawaban @Jon Skeet.
Anda harus menghitung semua jenis dan memeriksa masing-masing apakah itu mewarisi yang Anda cari.
Beberapa kode seperti yang ada di pertanyaan ini semoga bermanfaat untuk Anda.
Pertimbangkan untuk menggunakan metode ini (ditulis untuk PCL):
public IEnumerable<Type> FindDerivedTypes( Assembly assembly, Type baseType )
{
TypeInfo baseTypeInfo = baseType.GetTypeInfo();
bool isClass = baseTypeInfo.IsClass, isInterface = baseTypeInfo.IsInterface;
return
from type in assembly.DefinedTypes
where isClass ? type.IsSubclassOf( baseType ) :
isInterface ? type.ImplementedInterfaces.Contains( baseTypeInfo.AsType() ) : false
select type.AsType();
}