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

时间:2017-10-27 14:00:39

标签: c# inheritance extension-methods

为什么在子类中,我不能通过直接调用基类来调用为派生类定义的扩展方法(我得到一个编译错误,基类不包含扩展方法的定义)。 但相反,当我直接从子intance调用它时,我可以调用extention方法而没有任何编译错误。 以下是我的问题的代码:

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}");
   }

}

3 个答案:

答案 0 :(得分:3)

当您调用扩展方法时,编译器会查看左侧引用的类型并找到最合适的方法。因此,当您致电this.ExtentionMethod时,this的类型将用于查找最佳方法。

因此,在您的情况下,编译器将查找具有Child第一个参数的扩展名。由于没有一个,它会找到一个Mother第一个参数(因为Child"是-a" Mother)。

使用base不进行强制转换 - 它用于访问基类的成员。由于扩展方法不是"成员",base不能达到预期的效果。

替代方案可能是将强制转换 this改为基类:

((Mother)this).ExtentionMethod(3);

虽然我会注意到您没有为派生类提供不同的扩展方法,但是对于您发布的内容,this.ExtensionMethod和{{之间没有区别1}}。将调用相同的方法(具有相同的输入值)。

答案 1 :(得分:0)

这是D Stanley's answer的扩展名。

如果您在 {/ em> 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}");
    }
}

然后在从子类和基类调用它之间存在区别。

Child内部

this.ExtentionMethod(3);

将调用Child版本。

((Mother)this).ExtentionMethod(3);

将调用Mother版本。

public void TestMethod()
{
    this.ExtentionMethod(3);
    ((Mother)this).ExtentionMethod(3);
}

将使用上述两种扩展方法生成以下输出:

  

儿童延伸方法3
  母亲延伸方法3

答案 2 :(得分:0)

其他答案提供了非常好的解释为什么你有问题,我想确保你知道最快的方法:

public void TestMethod()
{
   this.ExtentionMethod(3); 
   Extender.ExtentionMethod((Mother)this, 3);
}

如果您的编译器无法识别扩展方法,只需删除该语法糖。您仍然可以像常规的公共静态方法一样调用它,并传递参数,就像从不存在exension方法的this关键字一样。它不是或者,你仍然可以走老路。