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.
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:
- We start from the current type and walk up the BaseType until we reach the root type.
- We reverse the list, so when we iterate over it we start with the root type first.
- 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]
精彩评论