[英]Calling an extention method of a base class from child class
Why in a child class, i can not call the extention method defined for the derived class by calling the base class directly ( i get a compile error that the base class does not contain a definition for the extention method). 为什么在子类中,我无法通过直接调用基类来调用为派生类定义的扩展方法(我收到了一个编译错误,即基类不包含扩展方法的定义)。 But instead, i can call the extention method without any compile errors when i call it directly from the child intance.
但是,相反,当我直接从子实例调用它时,我可以在没有任何编译错误的情况下调用扩展方法。 Below is the code for my question :
以下是我的问题的代码:
using System;
using System.Reflection;
public class Program
{
public static void Main()
{
Child child = new Child();
child.TestMethod();
}
}
// Derived class
public class Mother
{
}
// Child class
public class Child : Mother
{
public Child() : base()
{
}
public void TestMethod()
{
this.ExtentionMethod(3);// Ok: no compile errors
base.ExtentionMethod(3);// Ko: Compilation error (line 27, col 8): 'Mother' does not contain a definition for 'ExtentionMethod'
}
}
public static class Extender
{
public static void ExtentionMethod(this Mother mother, int i)
{
Console.WriteLine($"Mother extention method {i}");
}
}
When you call an extension method, the compiler looks at the type of the reference on the left and finds the most appropriate method. 当您调用扩展方法时,编译器会在左侧查看引用的类型,并找到最合适的方法。 So when you call
this.ExtentionMethod
, the type of this
is used to find the best method. 因此,当您调用
this.ExtentionMethod
,将使用this
类型来查找最佳方法。
So in your case, the compiler will look for an extension with a Child
first parameter. 因此,在您的情况下,编译器将寻找带有
Child
优先参数的扩展。 Since there is not one, it will then find the one with a Mother
first parameter (since a Child
"is-a" Mother
). 由于没有一个,因此它将找到一个带有“
Mother
优先参数的参数(因为“ Child
”是“ Mother
)。
Using base
does not do a cast - it is used to access members of the base class. 使用
base
不会进行强制类型转换-它用于访问基类的成员。 Since extension methods are not "members", base
does not do what you expect it to do. 由于扩展方法不是“成员”,因此
base
不会执行您期望的操作。
An alternative might be to cast this
to the base class instead: 另一种可能是投
this
基类来代替:
((Mother)this).ExtentionMethod(3);
Although I would note that you don't have a different extension method for the derived class, so with what you posted there would be no difference between this.ExtensionMethod
and ((Mother)this).ExtensionBethod
. 虽然我要指出,你没有派生类不同的扩展方法,所以与你贴会有没有什么区别
this.ExtensionMethod
和((Mother)this).ExtensionBethod
。 The same method (with the same input values) are going to be called. 将调用相同的方法(具有相同的输入值)。
This an extension to D Stanley's answer . 这是D Stanley的答案的扩展。
If you had extension methods on both Mother
, and Child
, like this: 如果您在
Mother
和Child
上都具有扩展方法,如下所示:
public static class Extender
{
public static void ExtentionMethod(this Mother mother, int i)
{
Console.WriteLine($"Mother extention method {i}");
}
public static void ExtentionMethod(this Child child, int i)
{
Console.WriteLine($"Child extention method {i}");
}
}
Then there is a distinction between calling it from the sub-class vs the base-class. 然后,从子类和基类调用它之间是有区别的。
From inside Child
从
Child
里面
this.ExtentionMethod(3);
Will call the Child
version. 将调用
Child
版本。
((Mother)this).ExtentionMethod(3);
Will call the Mother
version. 将称为
Mother
版。
public void TestMethod()
{
this.ExtentionMethod(3);
((Mother)this).ExtentionMethod(3);
}
Would produce the following output with both extension methods from above: 使用以上两种扩展方法将产生以下输出:
child extention method 3
儿童扩展方法3
Mother extention method 3母亲扩展方法3
The other answers offer very good explanations why you have problems, I'd like to make sure you know the fastest way out of that mess: 其他答案提供了很好的解释,说明您为什么会遇到问题,我想确保您知道摆脱困境的最快方法:
public void TestMethod()
{
this.ExtentionMethod(3);
Extender.ExtentionMethod((Mother)this, 3);
}
If your compiler does not recognize the extension method, just remove that syntactical sugar. 如果您的编译器无法识别扩展方法,则只需删除该语法糖即可。 You can still call it just like a regular, public static method and pass the parameters just as if the
this
keyword for exension methods never existed. 您仍然可以像常规的公共静态方法一样调用它,并传递参数,就像用于扩展方法的
this
关键字不存在一样。 It's not either or, you can still go the old way. 也不是,或者您仍然可以沿用旧的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.