C# 扩展方法如何处理继承?
我知道魔术的前半部分。假设我有:C# 扩展方法如何处理继承?,c#,inheritance,extension-methods,C#,Inheritance,Extension Methods,我知道魔术的前半部分。假设我有: 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) {}
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
扩展名,因为Bar
比Foo
更具体,因此比采用Foo
实例的替代方法更匹配。这与解决不明确方法重载的方式没有太大区别
值得注意的是,此代码将调用FooExt.M()
:
这是因为扩展方法不是虚拟的。由于调用方法的变量类型为Foo
,因此扩展方法的Bar
版本甚至不会被考虑。扩展方法的绑定完全发生在编译时
在您指出的第二种情况下(对Wow
类型的变量调用扩展方法),将使用FooExt.M()
方法,因为没有更好的匹配方法
我测试了它,答案是BarExt
,但为什么
因为编译器将选择“最适合”调用的扩展方法。由于有一种方法直接获取条
,因此选择了该方法
如果我有另一个wow:Foo但没有WowExt.M(),当我调用wow.M()时会发生什么
同样,它将选择“最适合”使用的扩展。因为没有方法接受Wow
,但是一个方法接受它的父类Foo
,它将选择FooExt.M()
请记住,扩展方法实际上只是静态方法调用的语法糖,因此对它们应用与“普通”方法解析相同的规则。解析扩展方法时,将选择最特定的类型匹配。在第一种情况下,BarExt.M()
是最具体的(目标是Bar
,而不是Foo
)
在第二种情况下,没有Wow
扩展,因此最具体的匹配应该是FooExt.M()
只是一个计算的猜测,但我认为编译器会查看静态类型来选择它必须采用的类型。你试过这样的吗<代码>Foo myfoo=新条();myfoo.M()代码>+1。由于扩展方法只是静态方法,第一个参数在函数名之前移动,所以它们使用与常规方法完全相同的规则。
Foo bar = new Bar();
bar.M();