使用LINQ查找继承链底部的类

时间:2010-09-16 14:40:44

标签: c# linq reflection inheritance

给定一系列具有类的程序集,例如

  AssemblyA
    Customer
  AssemblyB
    Customer : AssemblyA.Customer
  AssemblyC
    Customer : AssemblyB.Customer

给定名称(不关注命名空间)Customer,我可以使用LINQ来查询程序集序列 在继承链的底部找到客户(在这种情况下是AssemblyC.Customer)?

3 个答案:

答案 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)

此工具可能会对您有所帮助:

http://www.red-gate.com/products/reflector/

答案 2 :(得分:0)

第一个问题是如何确定要搜索的程序集。 System.Reflection.Assembly提供了许多列出某些类型程序集的方法 - 例如GetReferencedAssemblies()将查找给定程序集引用的程序集 - 如果你有程序集C(引用B和A),则很有用,但如果你只是有汇编A(没有引用)。您也可以根据需要扫描磁盘或其他方法。

一旦确定了如何迭代程序集,请使用此项中的技术查找派生自相关类的类: Discovering derived types using reflection

递归地应用此逻辑,直到到达树的末尾。你问题的评论者是对的 - 树可能有多个分支。

我不知道你为什么要用Linq来做这件事 - Linq似乎不是为这类问题而建的。我个人没有找到一种在Linq内部进行递归或基于队列的操作的方法。我只是使用C#或VB普通语句而不是Linq。