2

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

4

2 回答 2

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

有评论者问

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

调用GetInterfaces()类型对象。

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

我的原始代码又是如何被破坏的?

好吧,假设例如你有一个类型

class D<T> {}

和一堂课

class E : D<int> {}

现在你问“给定E,列出X程序集中的所有类型,以便可以将类型的值E分配给类型的变量X”。嗯,D<T>是在大会;是D<T>这样的类型吗?不可以。 AnE可以分配给 type 的变量D<int>,而不是 type 的变量D<T>

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

于 2015-03-17T16:25:13.550 回答
1

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

于 2015-03-17T16:25:05.273 回答