2009-09-22 33 views
3

System.Type類提供了一個GetInterfaces()方法,該方法「獲取由當前類型實現或繼承的所有接口」。 問題在於「GetInterfaces方法不會以特定的順序返回接口,例如按字母順序或聲明順序。您的代碼不能依賴於接口的返回順序,因爲順序會有所不同。 然而,在我的情況下,我需要隔離和暴露(通過WCF)只有接口層次結構的葉子接口,也就是那個層次結構中其他接口沒有繼承的接口。例如,請考慮以下層次檢索類型的葉子接口

interface IA { } 
interface IB : IA { } 
interface IC : IB { } 
interface ID : IB { } 
interface IE : IA { } 
class Foo : IC, IE {} 

Foo的葉接口IC和IE瀏覽器,而GetInterfaces()將返回所有5個接口(IA..IE)。 還提供了FindInterfaces()方法,允許您使用您選擇的謂詞過濾上述接口。

我目前的實施情況如下。它是O(n^2),其中n是類型實現的接口數量。我想知道是否有更加優雅和/或有效的方式。

private Type[] GetLeafInterfaces(Type type) 
    { 
     return type.FindInterfaces((candidateIfc, allIfcs) => 
     { 
      foreach (Type ifc in (Type[])allIfcs) 
      { 
       if (candidateIfc != ifc && candidateIfc.IsAssignableFrom(ifc)) 
        return false;  
      } 
      return true; 
     } 
     ,type.GetInterfaces()); 
    } 

在此先感謝

回答

3

我不認爲你會發現一個簡單的解決這個。你的問題是,最後,Foo實際上實現了所有的接口,而不管它們的內部繼承層次。如果使用Ildasm或某些類似的工具檢查Foo,這變得明顯。請看下面的代碼:

interface IFirst { } 
interface ISecond : IFirst { } 
class Concrete : ISecond { } 

產生的IL代碼(從ILDASM轉儲):

.class private auto ansi beforefieldinit MyNamespace.Concrete 
     extends [mscorlib]System.Object 
     implements MyNamespace.ISecond, 
        MyNamespace.IFirst 
{ 
    .method public hidebysig specialname rtspecialname 
      instance void .ctor() cil managed 
    { 
    // Code size  7 (0x7) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: call  instance void [mscorlib]System.Object::.ctor() 
    IL_0006: ret 
    } // end of method Concrete::.ctor 

} // end of class MyNamespace.Concrete 

正如你可以看到,在這個層面上存在Concrete之間的關係,這兩個接口沒有差別。

+0

謝謝! 也許我的GetLeafInterfaces()函數可能對未來某個人有用,然後 –