如何从自己的类调用扩展方法而不进行强制转换?

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

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

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

 The name 'HelloWorld' does not exist in the current context 

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

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

有什么解释吗?

演员没有必要 – this部分是。 所以这很好用:

 return this.HelloWorld(); 

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

 expr.identifier ( ) expr.identifier ( args ) expr.identifier < typeargs > ( ) expr.identifier < typeargs > ( args ) 

这个调用:

 HelloWorld() 

不是那种forms,因为没有表达。

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

this.HelloWorld(); 没有铸造工作

记住扩展方法的工作原理:

您使用一个对象,编译器会知道该类型,然后它可以将其解析为扩展方法。 如果没有使用对象,那么它将无法解决它。

不是一个真正的答案,但是太长,无法适应评论部分……

让我们来看下面的例子,我认为这很常见:

 public class DoubleSet : List { public IEnumerable Square() { return this.Select( x => x*x ); } } 

这是一个非常有效的观点,编译器无需正确解释Select方法。

但是我认为在某些方面,强加点符号突出了我们正在处理扩展方法的事实,因此, 扩展方法只会通过公共访问器访问当前实例的成员,即使你’在类的私有范围内调用它

它向代码阅读器明确指出,扩展方法会将“this”实例视为不知道其内部状态的任何内容。 实际上,对象的类对于扩展方法是完全未知的(因为扩展方法只知道接口)

如果代码只是:

  public IEnumerable Square() { return Select( x => x*x ); } 

你正在处理实际调用IList.GetEnumerator的IEnumerable.Select并逐个获取每个元素以调用x => x * x函数。