为什么 C# 扩展方法必须在静态类中定义?
我知道 C# 扩展方法必须是静态的。我不明白的是为什么这些扩展不能在非静态类或通用类中定义?
更新:我对这个设计决定背后的原因感兴趣。
I understand that C# extension methods must be static. What I don't understand is why these extensions can't be defined in non static classes or generic ones?
Update: I am interested in the reason behind this design decision.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这更多的是一种观察而不是答案,但是......
当您调用实例方法时,对您正在调用的对象的引用将作为方法调用中的第一个参数推送到堆栈上。第一个参数是“this”并且是隐式完成的。
当您定义扩展方法时,您显式地将“this”定义为第一个参数。
如果您可以在同一个类中定义扩展方法和实例方法,即定义具有相同名称的方法,并且实际上在“this”参数时具有相同的参数,那么方法解析是否可能会令人困惑包括在内。
This is more of an observation than an answer, but...
When you call an instance method, a reference to the object you are calling is pushed onto the stack as the first argument in your method call. That first argument is "this" and is done implicitly.
When you define an extension method, you explicitly define a "this" as the first argument.
Is it possible that method resolution would be confusing if you could define extension methods and instance methods in the same class i.e. defining methods with the same name and, in effect, the same parameters when the "this" parameter is included.
看一下 .NET C# 规范的这一部分:
这个片段来自 Jon Skeet 的回答:
Take a look to this piece of the .NET C# specification:
And this fragment from Jon Skeet's answer:
因为规范是这么说的……现在他们这样编写规范可能有充分的理由。
它们不能在泛型类中声明的原因非常明显:考虑到扩展方法的调用方式,您将在哪里指定类的类型参数?
为什么它必须是静态类的原因不太明显,但我认为这是有道理的。静态类的主要用例是将辅助方法组合在一起(例如
Path
、Directory
、ProtectedData
...),扩展方法是基本上是辅助方法。例如,能够创建Enumerable
或Queryable
的实例是没有意义的。Because the spec says so... Now there are probably good reasons why they wrote the spec this way.
The reason why they can't be declared in generic classes is quite obvious: given the way extension methods are called, where would you specify the type argument for the class?
The reason why it must be a static class is less obvious, but I think it makes sense. The main use case for static classes is to group helper methods together (e.g.
Path
,Directory
,ProtectedData
...), and extension methods are basically helper methods. It wouldn't make sense to be able to create an instance ofEnumerable
orQueryable
, for example.