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

Jac*_*ack 2 c# reflection inherited

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

假设这个类:

class B { }
class A : B { }
class C :TreeNode { }
Run Code Online (Sandbox Code Playgroud)

然后:

GetInheritedTypes(typeof(A)); //typeof(B)
GetInheritedTypes(typeof(C)); // 0 items
Run Code Online (Sandbox Code Playgroud)

列出它们的方法:

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

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

Eri*_*ert 9

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

因为TreeNode不在同一个组件中C.您的查询是"来自与C相同的程序集中的所有类型,给我C可分配的那些".

但我怀疑你的实际问题是:

如何列出给定类型的所有基本类型?

不会对装配中的所有类型进行搜索,并检查哪些类型是可分配的.这就像试图通过询问你所在城市的每个人"你是杰克的妈妈吗?"来弄清楚你的妈妈是谁.而不是问杰克"谁是你的妈妈?"

这样的事情会好得多:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

一位评论者问道

如果你想获得所有实现的接口怎么办?

调用GetInterfaces()类型对象.

(这篇文章的早期版本建议获得接口的传递闭包;我忘记了GetInterfaces已经这样做了.)

我的原始代码怎么破坏了?

好吧,假设你有一个类型

class D<T> {}
Run Code Online (Sandbox Code Playgroud)

和一个班级

class E : D<int> {}
Run Code Online (Sandbox Code Playgroud)

现在你问"给定E,列出X程序集中的所有类型,以便E可以将类型的值赋给类型的变量X".好吧,D<T>是在集会中; 是D<T>这样的类型?号的E可分配给类型的变量D<int>,类型的不变量D<T>.

"可分配"关系和"继承自"关系有很多重叠,但它们完全没有相同的关系,所以不要假装它们是相同的.