我写了一个小方法来列出继承的类型,但它不适用于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)
?
答案 0 :(得分:9)
为什么GetInheritedTypes(typeof(C))返回0项而不是Typeof(TreeNode)?
因为TreeNode
与C
不在同一个程序集中。您的查询是&#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
位于不同的程序集中。