2009-09-22 30 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()函数可能对未来某个人有用,然后 –