给定一系列具有类的程序集,例如
AssemblyA
Customer
AssemblyB
Customer : AssemblyA.Customer
AssemblyC
Customer : AssemblyB.Customer
给定名称(不关注命名空间)Customer,我可以使用LINQ来查询程序集序列 在继承链的底部找到客户(在这种情况下是AssemblyC.Customer)?
答案 0 :(得分:1)
IEnumerable<Assembly> assemblies = ...
Assembly assemblyA = ...
// Since you say the only fact you wish to use about the class is that it
// is named 'Customer' and it exists in Assembly A, this is just about the
// only way to construct the Type object. Pretty awful though...
Type customerType = assemblyA.GetTypes()
.Single(t => t.Name == "Customer");
// From all the types in the chosen assemblies, find the ones that subclass
// Customer, picking the one with the deepest inheritance heirarchy.
Type bottomCustomerType = assemblies.SelectMany(a => a.GetTypes())
.Where(t => t.IsSubclassOf(customerType))
.OrderByDescending(t => t.GetInheritanceDepth())
.First();
...
public static int GetInheritanceDepth(this Type type)
{
if (type == null)
throw new ArgumentNullException("type");
int depth = 0;
// Keep walking up the inheritance tree until there are no more base classes.
while (type != null)
{
type = type.BaseType;
depth++;
}
return depth;
}
答案 1 :(得分:0)
此工具可能会对您有所帮助:
答案 2 :(得分:0)
第一个问题是如何确定要搜索的程序集。 System.Reflection.Assembly提供了许多列出某些类型程序集的方法 - 例如GetReferencedAssemblies()将查找给定程序集引用的程序集 - 如果你有程序集C(引用B和A),则很有用,但如果你只是有汇编A(没有引用)。您也可以根据需要扫描磁盘或其他方法。
一旦确定了如何迭代程序集,请使用此项中的技术查找派生自相关类的类: Discovering derived types using reflection
递归地应用此逻辑,直到到达树的末尾。你问题的评论者是对的 - 树可能有多个分支。
我不知道你为什么要用Linq来做这件事 - Linq似乎不是为这类问题而建的。我个人没有找到一种在Linq内部进行递归或基于队列的操作的方法。我只是使用C#或VB普通语句而不是Linq。