M4N*_*M4N 75 c# extension-methods
我已经为ASP.NET MVC ViewPage创建了一个扩展方法,例如:
public static class ViewExtensions
{
    public static string Method<T>(this ViewPage<T> page) where T : class
    {
        return "something";
    }
}
从View(派生自ViewPage)中调用此方法时,我得到错误" CS0103:当前上下文中不存在名称'Method' "除非我使用this关键字来调用它:
<%: Method() %> <!-- gives error CS0103 -->
<%: this.Method() %> <!-- works -->
为什么this需要关键字?或者没有它可以工作,但我错过了什么?
(我认为这个问题肯定有重复,但我找不到一个)
更新:
正如Ben Robinson所说,调用扩展方法的语法只是编译器糖.那为什么编译器不能自动检查当前类型的基类型的扩展方法而不需要this关键字?
Eri*_*ert 49
几点:
首先,建议的功能(在扩展方法调用上隐含"this.")是不必要的.LINQ查询理解需要扩展方法才能按照我们想要的方式工作; 接收器总是在查询中声明,因此没有必要支持隐式,以使LINQ工作.
其次,功能的工作对扩展方法更一般的设计:即,扩展方法允许你扩展类型,你不能扩展自己,可能是因为它是一个接口,你不知道实现,或者是因为你做知道实现,但没有源代码.
如果你是在场景中你使用的扩展方法的类型该类型中,那么你就可以访问源代码.为什么你首先使用扩展方法呢?如果您可以访问扩展类型的源代码,则 可以自己编写实例方法,然后根本不必使用扩展方法!然后,您的实现可以利用对对象的私有状态的访问权限,而扩展方法则无法访问.
在您有权访问的类型中更容易使用扩展方法,这鼓励在实例方法上使用扩展方法.扩展方法很棒,但如果你有一个实例方法通常更好.
鉴于这两点,负担不再落在语言设计者解释为什么该功能也不会存在.它现在落在你身上,以解释为什么它应该.功能与它们相关的成本很高.此功能不是必需的,并且违反了扩展方法的规定设计目标; 我们为什么要承担实施它的成本?说明此功能启用了哪些引人注目的重要方案,我们将考虑将来实施它.我没有看到任何令人信服的重要场景证明这一点,但也许有一个我错过了.
没有它,编译器只会将其视为静态类中的静态方法,该方法将页面作为第一个参数.即
// without 'this'
string s = ViewExtensions.Method(page);
与
// with 'this'
string s = page.Method();
在实例方法中,'this'以透明方式隐式传递给每个方法,因此您可以访问它提供的所有成员.
扩展方法是静态的.通过调用Method()而不是this.Method()或者Method(this),您不会告诉编译器传递给方法的内容.
你可能会说'为什么它只是意识到调用对象是什么并将其作为参数传递?'
答案是扩展方法是静态的,可以从静态上下文中调用,其中没有"this".
我猜他们可以在编译期间检查一下,但说实话,这可能是非常少的回报.说实话,我认为在取消扩展方法调用的一些显式方面没什么好处.事实上,它们可能被误认为是方法,这意味着它们有时可能非常不直观(例如,不会抛出NullReferenceExceptions).我有时认为他们应该为扩展方法引入一个新的"管道前移"式操作符.