简体   繁体   English

从子类中调用基类的扩展方法

[英]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: 如果您在MotherChild具有扩展方法,如下所示:

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.

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