3

System.Type类提供了一个GetInterfaces () 方法,“获取当前Type 实现或继承的所有接口” 。问题是“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());
    }

提前致谢

4

1 回答 1

3

我不认为你会找到一个简单的解决方案。您的问题是,最终,Foo实际上实现了所有接口,而不管它们的内部继承层次结构如何。如果您Foo使用 Ildasm 或其他类似工具进行检查,这将变得很明显。考虑以下代码:

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,两个接口之间的关系没有区别。

于 2009-09-22T14:18:00.663 回答