开发者

How to form a tree that represents the inheritance tree of an interface?

I know how to get all interfaces of T using typeof(T).GetInterfaces() but I need the exact inheritance tree.

Is it possible to resolve this somehow from the existing refl开发者_Python百科ection API?

EDIT: Allow me to clarify:

interface Base1 {}
interface Base2 {}
interface Foo : Base1
interface Final : Foo, Base2

I would like to form a tree that represents the hierarchy of Final.

I already have a dependency on NGenerics so using it for tree implementation is not a problem.


Let's see. As far as I know, there's no BCL way to only get the interfaces that are actually implemented on a specific type but exclude any interfaces that type inherited. So we'll have to roll our own:

public static Dictionary<Type, IEnumerable<Type>> GetInterfaceHierarchyMap(this Type type)
{
    List<Type> typeAncestry = new List<Type>();
    Type ancestor = type;
    while(ancestor != null)
    {
        typeAncestry.Add(ancestor);
        ancestor = ancestor.BaseType;
    }
    Dictionary<Type, IEnumerable<Type>> interfaceMaps = new Dictionary<Type, IEnumerable<Type>>();
    foreach(Type childType in typeAncestry.Reverse<Type>())
    {
        var mappedInterfaces = interfaceMaps.SelectMany(kvp => kvp.Value);
        var allInterfacesToPoint = childType.GetInterfaces();
        interfaceMaps.Add(childType, allInterfacesToPoint.Except(mappedInterfaces));
    }
    return interfaceMaps;
}

One step at a time:

  1. We start from the current type and walk up the BaseType until we reach the root type.
  2. We reverse the list, so when we iterate over it we start with the root type first.
  3. For each type down the chain, we get all interfaces applied to that type and inherited from ancestor types, then we use Except to eliminate all the ones we already found in previous iterations.

This will treat duplicate interface requirements as superfluous - i.e., if one of your ancestor types implements IDisposable and your type does as well, only the earliest implementation will be counted.

A hypothetical result of this method would be a dictionary that looks something like:

[object] - []
[BaseBaseClass] - [ISomeInterface]
[BaseClass] - [IAnotherInterface, IOneMore]
[ConcreteClass] - [IYetAnother]
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜