扩展方法的继承

时间:2014-07-18 02:19:08

标签: c# inheritance extension-methods multiple-inheritance

继承如何在C#中使用扩展方法

假设您有接口IAIB : IAIC以及类Foo : IB, IC,现在可以定义扩展方法:

public static class Extensions {

    public static void Bar (this IA instance) {
        //Some code
    }

    public static void Bar (this IB instance) {
        //Some code
    }

    public static void Bar (this IC instance) {
        //Some code
    }

    public static void Bar (this Foo instance) {
        //Some code
    }

}

编译器如何确定Foo.Bar()的行为?基于经验测试,编译器总是选择最具体的实例(如正常调用),而不使用动态绑定(因为this注释)我认为是更“语法”的糖。 ..

如果两个或多个类在继承层次结构中定义来自不同分支的方法,则调用是不明确的。在这种情况下,有没有办法定义一种方法优先于另一种方法?

上述声明是否正确?

1 个答案:

答案 0 :(得分:4)

继承确实很重要,但更重要的是命名空间,来自C#规范:

  

如果调用的正常处理发现不适用   方法,尝试将构造作为扩展进行处理   方法调用。

可以在C#规范7.6.5.2 Extension method invocations中找到确切的流程和示例。解析过程(其中C是可能的类型分辨率的集合,M是扩展方法的集合):

  

对C的搜索进行如下:
  •从最近的开始   封闭名称空间声明,继续每个封闭   名称空间声明,以包含的编译结束   单位,连续尝试找到一个候选集   扩展方法:

     

o如果给定的命名空间或编译单元   直接包含符合条件的非泛型类型声明Ci   扩展方法Mj,然后是那些扩展方法的集合   候选人集。

     

o如果使用命名空间指令导入名称空间   在给定的命名空间或编译单元中直接包含   非泛型类型声明Ci具有合格的扩展方法Mj,   然后这些扩展方法的集合是候选集。

     

•如果没有   候选集可以在任何封闭的命名空间声明中找到   编译单元,发生编译时错误。

     

•否则,超载   如(第7.5.3节)所述,将分辨率应用于候选集。   如果未找到单个最佳方法,则会发生编译时错误。

     

•C是将最佳方法声明为扩展名的类型   方法。使用C作为目标,然后将方法调用作为a处理   静态方法调用(第7.5.4节)。

如果我理解正确的话,意味着它在编译时在最近的命名空间中选择最好的扩展方法。理解没有动态调用是非常重要的,分辨率是静态完成的(即在编译时)。