如何形成一个代表接口继承树的树?

时间:2010-11-05 00:46:48

标签: c# reflection interface

我知道如何使用typeof(T).GetInterfaces()获取T的所有接口,但我需要确切的继承树 是否有可能从现有的反射API以某种方式解决这个问题?

编辑: 请允许我澄清一下:

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

我想形成一个代表Final的层次结构的树 我已经依赖NGenerics,所以使用它来实现树不是问题。

1 个答案:

答案 0 :(得分:1)

我们来看看。据我所知,没有BCL方式获取实际在特定类型上实现的接口,但排除任何继承类型的接口。所以我们必须自己动手:

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

一次一步:

  1. 我们从当前类型开始,然后走近BaseType,直到我们到达根类型。
  2. 我们反转列表,所以当我们迭代它时,我们首先从根类型开始。
  3. 对于链中的每个类型,我们将所有接口应用于该类型并从祖先类型继承,然后我们使用Except来消除我们在先前迭代中已经找到的所有接口。
  4. 这会将重复的接口要求视为多余的 - 即,如果您的一个祖先类型实现了IDisposable并且您的类型也是如此,那么只会计算最早的实现。

    此方法的假设结果将是一个类似于:

    的字典
    [object] - []
    [BaseBaseClass] - [ISomeInterface]
    [BaseClass] - [IAnotherInterface, IOneMore]
    [ConcreteClass] - [IYetAnother]