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

时间:2015-03-17 16:14:06

标签: c# reflection inherited

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

答案 0 :(得分:9)

  

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

因为TreeNodeC不在同一个程序集中。您的查询是&#34;来自与C相同的程序集中的所有类型,给我那些C可分配给&#34;。

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

  

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

搜索程序集中的所有类型,并检查哪些类型是可分配的。这就像试图通过询问你所在城市的每个人一样弄清楚你的妈妈是谁?你是杰克的妈妈吗?&#34;而不是问杰克&#34;谁是你的妈妈?&#34;。

这样的事情会好得多:

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> {}

现在您要求{#1}}给出E,列出程序集中的所有类型X,以便将类型E的值分配给X类型的变量1}}&#34 ;.好吧,D<T>在集会中;是D<T>这样的类型?不可以。E可分配给D<int>类型的变量,而不是D<T>类型的变量。

&#34;可分配&#34;关系和&#34;继承自&#34;关系有很多重叠,但它们根本不是相同的关系,所以不要假装它们是。

答案 1 :(得分:1)

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