获取继承类型列表并不适用于所有类型

Getting list of Inherited types doesn't work for all types

我写了一个小方法来列出继承的类型,但它不适用于 TreeNode 例如:

假设这个 类:

class B { }
class A : B { }
class C :TreeNode { }

然后:

GetInheritedTypes(typeof(A)); //typeof(B)
GetInheritedTypes(typeof(C)); // 0 items

列出方法:

List<Type> GetInheritedTypes(Type baseType) 
{ 
    return Assembly.GetAssembly(baseType)
                   .GetTypes()
                   .Where(type => type != baseType && type.IsAssignableFrom(baseType))
                   .ToList(); 
} 

为什么 GetInheritedTypes(typeof(C)) 返回 0 个项目而不是 Typeof(TreeNode)

您只是在与 C 相同的程序集中枚举 类,并且可能 TreeNode 位于不同的程序集中。

Why is GetInheritedTypes(typeof(C)) returning 0 items instead of Typeof(TreeNode)?

因为TreeNodeC不在同一个程序集中。您的查询是 "from all the types in the same assembly as C, give me the ones that C is assignable to".

不过我怀疑您的实际问题是:

How do I list all the base types of a given type?

而不是 对程序集中的所有类型进行搜索并检查哪些类型是可分配的。这就像试图通过询问您所在城市 "are you Jack's mom?" 的每个人而不是询问 Jack "who's your mom?".

来弄清楚您的妈妈是谁

像这样会好得多:

public static IEnumerable<Type> BaseTypes(this Type type)
{
    if (type == null) throw new ArgumentNullException("type");
    Type baseType = type;
    while(true)
    {
        baseType = baseType.BaseType;
        if (baseType == null) 
            break;
        yield return baseType;
    }
}

评论者提问

what if you want to get all the implemented interfaces?

在类型对象上调用 GetInterfaces()

(此 post 的早期版本建议获取接口的传递闭包;我忘记了 GetInterfaces 已经这样做了。)

How else was my original code broken?

嗯,假设你有一个类型

class D<T> {}

和一个class

class E : D<int> {}

现在你问"given E, list all the types X in the assembly such that a value of type E may be assigned to a variable of type X"。好吧,D<T> 在集会中; D<T>是这样的类型吗?否。E 可分配给类型 D<int> 的变量,而不是类型 D<T>.

的变量

"assignable"关系和"inherits from"关系有很多重叠,但它们根本不是相同的关系,所以不要'不要假装他们是。