如何从自己的类调用扩展方法而不进行强制转换?
我试图在我自己的类上调用扩展方法 ,但它无法编译。 考虑以下代码行:
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函数。