【发布时间】:2010-03-02 10:57:01
【问题描述】:
使用反射,是否可以发现从给定类型派生的所有类型?
大概范围将限制在单个程序集中。
【问题讨论】:
标签: c# .net reflection
使用反射,是否可以发现从给定类型派生的所有类型?
大概范围将限制在单个程序集中。
【问题讨论】:
标签: c# .net reflection
几乎和达林的一样,但是给你..
public static List<Type> FindAllDerivedTypes<T>()
{
return FindAllDerivedTypes<T>(Assembly.GetAssembly(typeof(T)));
}
public static List<Type> FindAllDerivedTypes<T>(Assembly assembly)
{
var derivedType = typeof(T);
return assembly
.GetTypes()
.Where(t =>
t != derivedType &&
derivedType.IsAssignableFrom(t)
).ToList();
}
类似:
var output = FindAllDerivedTypes<System.IO.Stream>();
foreach (var type in output)
{
Console.WriteLine(type.Name);
}
输出:
NullStream
SyncStream
__ConsoleStream
BufferedStream
FileStream
MemoryStream
UnmanagedMemoryStream
PinnedBufferMemoryStream
UnmanagedMemoryStreamWrapper
IsolatedStorageFileStream
CryptoStream
TailStream
【讨论】:
IsAssignableFrom 而不是IsSubclassOf 来说明接口。但是在接口上调用它也会返回它的实现类。
var derivedTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsSubclassOf(typeof(A))
select t;
【讨论】:
A类型的接口或类。
IsSubclassOf method 名称具有误导性。实际上,它为派生类返回true。
var types = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(t => typeof(SomeBaseType).IsAssignableFrom(t) &&
t != typeof(SomeBaseType))
.ToArray();
【讨论】:
我将@Hath 的优秀答案重写为扩展方法:
public static class TypeExtensions
{
public static List<Type> GetAllDerivedTypes(this Type type)
{
return Assembly.GetAssembly(type).GetAllDerivedTypes(type);
}
public static List<Type> GetAllDerivedTypes(this Assembly assembly, Type type)
{
return assembly
.GetTypes()
.Where(t => t != type && type.IsAssignableFrom(t))
.ToList();
}
}
用法:
var listOfDerived = typeof(MyClass).GetAllDerivedTypes();
【讨论】:
IsAssignableFrom 而不是IsSubclassOf?也许你想支持接口?但该结果将包括实现类。