2011-06-06 106 views
10

这是一个人为的例子:从派生类中调用C#基类扩展方法?

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文件中有所有适当的使用语句,所以我不确定发生了什么。

回答

18

尝试调用它像this

this.MyMethod("test"); 
+0

这样做了。谢谢。我假设'这个'。并不是必需的,因为我期望它可以像来自基类的其他常规函数一样工作。 – 2011-06-06 17:02:09

+2

@Robert Dailey,扩展方法总是需要一些实例来调用它们,并且在这个实例中声明的类的上下文中是'this'。这只是一个小小的*不便之处*,它不能与您从中获得的所有好处进行比较:-) – 2011-06-06 17:07:27

+1

错误的扩展方法不需要实例来运行它们,因为它们是静态方法。您可以通过传递参数来将扩展方法调用为静态方法。但是,对于在扩展方法声明中标记为“this”的参数,“base”不是有效的参数值。 – Tengiz 2012-11-05 16:45:38

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 
    } 
} 
+0

编译器不会失败,它会在添加“this”关键字时找到方法。我测试了它。 – 2011-06-06 17:13:55

+0

@Jalal噢,我原封不动地留下了原来的评论 – asawyer 2011-06-06 17:44:37

4

下面是备用溶液(由我优选):

(this as MyInterface).MyMethod("test"); 

为什么呢? - 因为之前提供的解决方案在扩展方法调用类的“新”方法(属性也是方法)的情况下不起作用。在这种情况下,您可能会可能打算对基类/接口声明的类型调用扩展方法,该类型的行为可能与派生类/接口的行为不同。

此外,此解决方案将适用于“新建”和“覆盖”方法,因为虚拟“覆盖”无论如何将调用派生版本,这也是意图。

编辑:这可能是无关紧要的,如果你真的不想传递“基”的扩展方法,而是让它采取“这个”。但是,你必须考虑行为差异。

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

相关问题