在派生类中如何调用C#基类的扩展方法?

10

这是一个人为制造的例子:

public static class MyExtensions
{
  public static void MyMethod( this MyInterface obj, string txt )
  {
  }
}

interface MyInterface {}

public MyDerived : MyInterface
{
  void DoStuff()
  {
    MyMethod( "test" ); // fails; compiler can't find MyMethod?
  }
}

在我上面的例子中,我试图从我的派生类中调用分配给接口的扩展方法。编译器在这里失败,并表示MyMethod不存在于当前上下文中。我在CS文件中拥有所有适当的using语句,所以我不知道发生了什么。

4个回答

19

尝试像这样调用它:this

this.MyMethod("test");

这样做就可以了。谢谢。我以为不需要加上“this.”,因为我期望它像来自基类的任何其他普通函数一样工作。 - void.pointer
2
@Robert Dailey,扩展方法总是需要一些实例来调用它们,在声明它们的类的上下文中,这个实例就是this。这只是一个小小的不便,无法与你从中获得的所有好处相比 :-) - Darin Dimitrov
1
错误,扩展方法不需要实例来运行它们,因为它们是静态方法。您可以通过向其传递参数来将扩展方法调用为静态方法。但是,在扩展方法声明中标记为“this”的参数的有效参数值不是“base”。 - Tengiz

4
这里给出了备选解决方案(是我个人偏爱的方法):
(this as MyInterface).MyMethod("test");

为什么? - 因为之前提供的解决方案在扩展方法调用类的“new”方法(属性也是一种方法)时无法工作。在这种情况下,您可能想要在由基类/接口声明的类型上调用扩展方法,这可能会与派生类/接口的行为不同。

此外,此解决方案将适用于“new”和“override”方法,因为虚拟的“override”将调用派生版本,这也是预期的。

编辑:如果您真的不想将“base”传递给扩展方法,而是允许它采取“this”,则此内容可能不相关。但是,您必须考虑行为差异。

还有,有趣的是,作为对Darin Dimitrov评论的回答:扩展方法不需要实例来运行它们,因为它们是静态方法。您可以通过向其传递参数来调用扩展方法为静态方法。然而,在扩展方法声明中标记有“this”的参数的参数值中,“base”不是有效的参数值,如果我是MS,这将简化扩展方法的一般使用。


3
尝试使用以下方式进行调用:
this.MyMethod("test");

0

将调用更改为

this.MyMethod("test")

这段代码可以编译:

public static class MyExtensions
{
  public static void MyMethod( this MyInterface obj, string txt )
  {
  }
}

public interface MyInterface {}

public class MyDerived : MyInterface
{
  void DoStuff()
  {
    this.MyMethod( "test" ); // works now
  }
}

不,编译器不会失败,并且当添加“this”关键字时,它将找到该方法。我已经测试过了。 - Jalal Said
@Jalal 噢,我把原始评论保留了下来。 - asawyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接