繁体   English   中英

扩展方法如何与继承一起使用?

[英]How do extension methods work with inheritance?

我知道魔法的前半部分。 假设我有:

public class Foo {}
public class static FooExt
{
    public static void M(this Foo f) {}
}

当我调用foo.M() ,编译器将其更改为FooExt.M(foo)

但继承怎么样? 例如:

public class Bar : Foo {}
public class static BarExt
{
    public static void M(this Bar b) {} 
}

当我调用bar.M()时,它会调用FooExt.M()还是BarExt.M() 事实上我测试了它,答案是BarExt ,但为什么呢? 当我打电话给wow.M()时会发生什么?如果我有另一个Wow : Foo但没有WowExt.M()

编译器将查找其参数调用站点上的参数最匹配的扩展方法。 如果你有一个Bar类型的变量,那么将使用BarExt扩展,因为BarFoo更具体的类型,因此比采用Foo实例的替代方法更紧密地匹配。 这与模糊方法重载的解决方式确实没有什么不同。

值得注意的是,此代码将调用FooExt.M()

Foo bar = new Bar();
bar.M();

这是因为扩展方法不是虚拟的。 由于您调用方法的变量是类型Foo ,因此甚至不会考虑扩展方法的Bar版本。 扩展方法的绑定完全在编译时发生。

在你指出的第二种情况下(在Wow类型的变量上调用扩展方法),将使用FooExt.M()方法,因为没有更好的匹配。

我测试了它,答案是BarExt ,但为什么呢?

因为编译器会选择“最适合”调用的扩展方法。 由于有一种直接采用Bar的方法,因此选择了一种。

当我打电话给wow.M()时会发生什么?如果我有另一个Wow:Foo但没有WowExt.M()?

同样,它将选择“最适合”使用的扩展名。 既然没有采用Wow方法,但确实采用它的父类Foo它会选择FooExt.M()

请记住,扩展方法实际上只是静态方法调用的语法糖,因此相同的规则适用于它们作为“正常”方法解析。

解析扩展方法时,将选择最具体的类型匹配。 在第一种情况下, BarExt.M()是最具体的(目标是Bar而不是Foo )。

在第二种情况下,没有Wow扩展,因此最具体的匹配将是FooExt.M()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM