代码之家  ›  专栏  ›  技术社区  ›  Jack

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

  •  2
  • Jack  · 技术社区  · 10 年前

    我编写了一个小方法来列出继承的类型,但它不适用于 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) ?

    2 回复  |  直到 10 年前
        1
  •  9
  •   Eric Lippert    10 年前

    为什么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;
        }
    }
    

    一位评论者问

    如果你想得到所有实现的接口呢?

    呼叫 GetInterfaces() 在类型对象上。

    (本文的早期版本建议获得接口的传递闭包;我已经忘记了 GetInterfaces 已经做到了。)

    我的原始代码是怎么被破坏的?

    例如,假设你有一个类型

    class D<T> {}
    

    还有一节课

    class E : D<int> {}
    

    现在你问“给定” E ,列出所有类型 X 在程序集中 E 可以分配给类型的变量 十、 “嗯, D<T> 在组件中;是 D<T> 这样的类型?编号An E 可分配给类型为的变量 D<int> ,不是类型的变量 D<T> .

    “可赋值”关系和“继承自”关系有相当多的重叠,但它们根本不是 相同的 关系,所以不要假装他们是。

        2
  •  1
  •   Jamiec    10 年前

    您只能枚举同一程序集中的类 C ,大概 TreeNode 位于不同的程序集中。