如何在不进行转换的情况下从自己的类调用扩展方法?

Kee*_*ker 10 .net c# extension-methods .net-4.0 c#-4.0

我试图在我自己的类上调用扩展方法,但它无法编译.请考虑以下代码行:

public interface IHelloWorld
{
}

public static class Extensions
{
    public static string HelloWorld(this IHelloWorld ext)
    {
        return "Hello world!";
    }
}

public class Test : IHelloWorld
{
    public string SaySomething()
    {
        return HelloWorld();
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上我正在扩展界面.我一直收到这个错误:

The name 'HelloWorld' does not exist in the current context
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释一下吗?当我做一个演员表似乎很好:

return ((Test)this).HelloWorld();

有什么解释吗?

Jon*_*eet 21

是没有必要的-的this一部分.所以这很好用:

return this.HelloWorld();
Run Code Online (Sandbox Code Playgroud)

第7.6.5.2节明确地讨论了表单的方法调用

expr.identifier ( )
expr.identifier ( args )
expr.identifier < typeargs > ( )
expr.identifier < typeargs > ( args )
Run Code Online (Sandbox Code Playgroud)

这个调用:

HelloWorld()
Run Code Online (Sandbox Code Playgroud)

不是那种形式,因为没有表达.

我不能立即清楚为什么语言是这样设计的(即为什么"隐含的这个"被排除在外),也许Eric Lippert将在后面添加一个答案.(答案很可能是"因为它需要花费很长时间才能进行规范,实现和测试,但收益相对较小.")但是,这个答案至少表明C#编译器坚持规范. ..

  • @EricLippert:我认为"向接口添加一个实用工具方法,根据接口成员工作"的用例是第一种情况的一个小例外.我们(或者至少可能不)真的想要将实例方法添加到接口或实现中.如果我们可以将实体方法*与body*一起添加到界面中(正如CLR团队之一在一次采访中所讨论的那样 - Vance Morrison可能会这样做吗?)那么调用该方法可能是完全合理的.扩展方法可以用作界面体限制的不完美的解决方法. (7认同)
  • 首先,我注意到如果你是编写调用站点的人`this.HelloWorld();`那么你就是那个可以将`HelloWorld`方法添加到当前类型的人.为什么在使用实例方法时可以使用扩展方法?扩展点方法的目的是使您能够将方法添加到您尚未拥有的类型*. (5认同)
  • @Eric:有时你会[想要没有公共基类的常见实例 - 方法](https://connect.microsoft.com/VisualStudio/feedback/details/552410/move-lots-of-helpful-方法-从列表到的IList-使用扩展的方法). (2认同)