Lai*_*uan 2 c# inheritance extension-methods
我知道魔法的前半部分.假设我有:
public class Foo {}
public class static FooExt
{
public static void M(this Foo f) {}
}
Run Code Online (Sandbox Code Playgroud)
当我调用foo.M()编译器时将其更改为FooExt.M(foo).
但继承怎么样?例如:
public class Bar : Foo {}
public class static BarExt
{
public static void M(this Bar b) {}
}
Run Code Online (Sandbox Code Playgroud)
当我调用bar.M()它会打电话FooExt.M()还是BarExt.M()?事实上,我测试了它,答案是BarExt,但为什么呢?wow.M()如果我有另一个Wow : Foo但没有,我会打电话怎么WowExt.M()办?
cdh*_*wie 10
编译器将查找其参数与调用站点上的参数最匹配的扩展方法.如果你有一个类型的变量,Bar那么BarExt将使用扩展,因为Bar它比一个类型更具体Foo,因此比采用Foo实例的替代方法更紧密地匹配.这与模糊方法重载的解决方式确实没有什么不同.
值得注意的是,此代码将调用FooExt.M():
Foo bar = new Bar();
bar.M();
Run Code Online (Sandbox Code Playgroud)
这是因为扩展方法不是虚拟的.由于您调用方法的变量是type Foo,因此Bar甚至不会考虑扩展方法的版本. 扩展方法的绑定完全在编译时发生.
在你指出的第二种情况下(在类型的变量上调用扩展方法Wow),FooExt.M()将使用该方法,因为没有更好的匹配.
我测试了它的答案是
BarExt,但为什么呢?
因为编译器会选择"最适合"调用的扩展方法.由于存在Bar直接采用的方法,因此选择该方法.
当我打电话给wow.M()时会发生什么?如果我有另一个Wow:Foo但没有WowExt.M()?
同样,它将选择"最适合"使用的扩展名.因为没有方法需要a Wow,但是Foo它会选择它的父类FooExt.M()
请记住,扩展方法实际上只是静态方法调用的语法糖,因此相同的规则适用于它们作为"正常"方法解析.