2010-11-05 30 views
2

我知道如何使用typeof(T).GetInterfaces()獲得T的所有接口,但我需要確切的繼承樹。
是否有可能從現有的反射API以某種方式解決這個問題?如何形成表示接口的繼承樹的樹?

編輯: 讓我澄清:

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

我想形成一個代表最終的層次結構樹。
我已經有了NGenerics的依賴,所以用它來實現樹並不是問題。

+0

你是什麼意思?你能舉一個具體的例子嗎? – 2010-11-05 01:06:30

+0

@Sam:看到下面的答案 – 2010-11-05 01:26:21

回答

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來消除之前迭代中已發現的所有接口。

這會將重複的接口要求視爲多餘 - 即,如果其中一個祖先類型實現了IDisposable,並且您的類型也如此,則只會計算最早的實現。

這種方法的一個假想的結果將是一本字典,看起來像:

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

不錯。但是如果我只處理接口呢?有關係嗎?實際上它確實是因爲它沒有基本類型。 – 2010-11-05 01:26:01

+0

@ the_drow不知道你的意思。接口不能從任何東西繼承,所以沒有層次結構。 – 2010-11-05 01:28:00

+0

@Rex M,Interfaces可以從可以創建層次結構的其他接口繼承。 – 2010-11-05 01:51:03