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

C# 从子类调用基类的扩展方法,c#,inheritance,extension-methods,C#,Inheritance,Extension Methods,为什么在子类中,我不能通过直接调用基类来调用为派生类定义的扩展方法(我得到一个编译错误,即基类不包含扩展方法的定义)。 但是,当我直接从子intance调用扩展方法时,我可以在没有任何编译错误的情况下调用它。 下面是我问题的代码: using System; using System.Reflection; public class Program { public static void Main() { Child child =

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

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

}

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

因此,在您的例子中,编译器将查找带有
子参数的扩展。由于没有一个,它将找到第一个参数为
母亲的参数(因为
子参数是-a
母亲)

使用
base
不会执行强制转换-它用于访问基类的成员。由于扩展方法不是“成员”,因此
base
不会执行您期望它执行的操作

另一种方法可能是将此
强制转换为基类:

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

尽管我要指出的是,对于派生类,您没有不同的扩展方法,因此您发布的
this.ExtensionMethod
((母亲)this.ExtensionBethod
之间没有区别。将调用相同的方法(具有相同的输入值)。

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

因此,在您的例子中,编译器将查找带有
子参数的扩展。由于没有一个,它将找到第一个参数为
母亲的参数(因为
子参数是-a
母亲)

使用
base
不会执行强制转换-它用于访问基类的成员。由于扩展方法不是“成员”,因此
base
不会执行您期望它执行的操作

另一种方法可能是将此
强制转换为基类:

((Mother)this).ExtentionMethod(3);
尽管我要指出的是,对于派生类,您没有不同的扩展方法,因此您发布的
this.ExtensionMethod
((母亲)this.ExtensionBethod
之间没有区别。将调用相同的方法(具有相同的输入值)。

这是对的扩展

如果在
母亲
孩子
上都有扩展方法,如下所示:

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);
将调用
子版本


将调用
母亲
版本


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

子扩展方法3
母亲延伸法3

这是对的扩展

如果在
母亲
孩子
上都有扩展方法,如下所示:

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);
将调用
子版本


将调用
母亲
版本


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

子扩展方法3
母亲延伸法3


其他答案很好地解释了你为什么会有问题,我想确保你知道最快走出困境的方法:

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

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

其他答案很好地解释了你为什么会有问题,我想确保你知道最快走出困境的方法:

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

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

你为什么还要调用
base.extensionmethod(3)
?这完全等同于
这个.extensionMethod(3)
,您的示例已经显示它是有效的。@BradleyUffner我知道,出于好奇,我想知道为什么不可能从基类调用它:)我唯一能看到需要这种行为的时候是,如果您也有一个
子版本的扩展方法,像
publicstaticvoidextensionmethod(这个Child-Child,inti){}
,那么你会在调用之前将
this
转换为
Mother
,就像@DStanley给出的答案一样。你为什么还要调用
base.extensionmethod(3)
?这完全等同于
这个.extensionMethod(3)
,您的示例已经显示它是有效的。@BradleyUffner我知道,出于好奇,我想知道为什么不可能从基类调用它:)我唯一能看到需要这种行为的时候是,如果您也有一个
子版本的扩展方法,像
publicstaticvoidextensionmethod(这个子对象,int i){}
,那么在调用之前,您可以将
this
转换为
Mother
,正如@DStanley给出的答案一样。感谢@D Stanley的回答,扩展方法不是为其定义的类的成员,而且base关键字不是派生的实例