我知道C#扩展方法必须是静态的。我不明白为什么这些扩展不能在非静态类或通用类中定义?
更新:我对此设计决定背后的原因感兴趣。
答案 0 :(得分:7)
这更多的是观察而不是答案,但是......
当您调用实例方法时,对您调用的对象的引用将作为方法调用中的第一个参数压入堆栈。第一个论点是“这个”并且是隐含地完成的。
定义扩展方法时,明确定义“this”作为第一个参数。
如果您可以在同一个类中定义扩展方法和实例方法,即定义具有相同名称的方法,并且实际上在“这个“参数包括在内。
答案 1 :(得分:4)
看看这篇.NET C#规范:
当方法的第一个参数包含this修饰符时,即 方法被认为是一种扩展方法。扩展方法只能 在非泛型的非嵌套静态类中声明。首先 扩展方法的参数除了可以没有修饰符 这个,参数类型不能是指针类型。
来自Jon Skeet's answer的这个片段:
我不清楚为什么所有这些限制都是必要的 - 除了潜在的编译器(和语言规范)简单性。一世 可以理解为什么将它限制为非泛型类型是有意义的,但我 不能立即明白为什么它们必须是非嵌套和静态的。一世 怀疑它使查找规则相当简单,如果你不这样做 不得不担心当前类型中包含的类型等,但我 敢说这是可能的。
答案 2 :(得分:1)
因为规范是这么说的......现在他们以这种方式编写规范可能是有充分理由的。
它们不能在泛型类中声明的原因很明显:给定扩展方法的调用方式,在哪里指定类的类型参数?
它必须是静态类的原因不太明显,但我认为这是有道理的。静态类的主要用例是将辅助方法组合在一起(例如Path
,Directory
,ProtectedData
...),扩展方法基本上是辅助方法。例如,能够创建Enumerable
或Queryable
的实例是没有意义的。