开发者

Using LINQ to find the class that is in the bottom of the inheritance chain

开发者 https://www.devze.com 2023-01-16 05:13 出处:网络
Given a sequence of assemblies with classes eg. AssemblyA Customer AssemblyB Customer : AssemblyA.Customer

Given a sequence of assemblies with classes eg.

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

Given the name (not taken care of namespace) Customer, can I use LINQ to query against the sequence of assemblies to find the customer at the bottom of the inheritan开发者_运维技巧ce chain (AssemblyC.Customer in this case) ?


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


This tool might help you:

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


The first question is how to determine the assemblies to be searched. System.Reflection.Assembly provides a number of methods for listing certain types of assemblies - for example GetReferencedAssemblies() will find assemblies referenced by a given assembly - useful if you have Assembly C (which refernces B and A), but not if you just have Assembly A (which references none). You could also scan the disk, or other methods, depending on your needs.

Once you've determined how to iterate assemblies, use the technique from this item to find classes that derive from the class in question: Discovering derived types using reflection

Apply this logic recursively until you reach the end of the tree. The commenter on your question is right - the tree may have multiple branches.

I do not know why you'd want to use Linq to do this - Linq does not seem built for this type of question. I have not personally found a way to do recursion or queue-based operations well inside of Linq. I'd just use C# or VB plain statements for this rather than Linq.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号