继承如何在C#中使用扩展方法。
假设您有接口IA
,IB : IA
和IC
以及类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
注释)我认为是更“语法”的糖。 ..
如果两个或多个类在继承层次结构中定义来自不同分支的方法,则调用是不明确的。在这种情况下,有没有办法定义一种方法优先于另一种方法?
上述声明是否正确?
答案 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节)。
如果我理解正确的话,意味着它在编译时在最近的命名空间中选择最好的扩展方法。理解没有动态调用是非常重要的,分辨率是静态完成的(即在编译时)。