扩展方法是否以任何实际的方式受益于成为静态类的一部分,而不是[理论上]命名空间的一部分

本文关键字:一部分 命名空间 理论上 静态类 是否 方法 任何实 于成 方式受 扩展 | 更新日期: 2023-09-27 18:32:19

当涉及到扩展方法时,类名似乎什么都不做,但提供了一个分组,这就是命名空间的作用。一旦我包含命名空间,我就会获得命名空间中的所有扩展方法。所以我的问题归结为:我是否可以从静态类中的扩展方法中获得一些价值?

我意识到将它们放入静态类是编译器的要求,但从组织的角度来看,允许在名称空间中定义扩展方法而不围绕它们的类似乎是合理的。以另一种方式重新表述上述问题:在某些情况下,作为开发人员,将扩展方法附加到类而不是附加到命名空间是否有任何实际好处或帮助?

我基本上只是想获得一些直觉、确认或洞察力 - 我怀疑以这种方式实现扩展方法可能是最简单的,并且不值得花时间允许扩展方法在命名空间中独立存在。

扩展方法是否以任何实际的方式受益于成为静态类的一部分,而不是[理论上]命名空间的一部分

也许你会在Eric Lippert的博客文章中找到一个令人满意的答案 为什么C#不实现"顶级"方法?(反过来由 SO 问题提示为什么 C# 不允许像 C++ 这样的非成员函数),因此(我的强调):

我一直被问到"为什么C#不实现功能X?"。这 答案总是相同的:因为没有人设计过,指定过, 实施、测试、记录和交付该功能。所有六个 这些事情对于实现功能是必要的。他们都花了 大量的时间、精力和金钱。功能不便宜,我们 努力确保我们只提供这些功能 这为我们的用户提供了最大的利益,因为我们 时间、精力和金钱预算有限。

我知道这样的笼统答案可能不会解决 具体问题。

在这种特殊情况下,明显的用户利益在过去没有 大到足以证明语言的复杂性是合理的,这将 接踵而至。通过限制不同语言实体在每个实体中的嵌套方式 其他我们 (1) 限制法律程序在一个共同的、容易的 理解风格,以及(2)可以定义"标识符 查找"规则是可理解的、可指定的、可实施的, 可测试和可记录。

通过将方法主体限制为始终位于结构或类中,我们可以更轻松地推理非限定的含义 在调用上下文中使用的标识符;这样的事情总是一个 当前类型(或基类型)的可调用成员。

对我来说,

将它们放在类中就是将相关函数分组到类中。同一命名空间中可能有许多扩展方法。如果我想为 DirectoryInfo 和 FileInfo 类编写一些扩展方法,我会在一个名为 DirectoryInfoExtensions 和 FileInfoExtensions 的 IO 命名空间中创建两个类。

您仍然可以像调用任何其他静态方法一样调用扩展方法。我不知道编译器是如何工作的,但如果为 .net 2 编译,也许输出程序集仍然可以被遗留的 .net 框架使用。这也意味着现有的反射库可以工作并用于运行扩展方法,而无需进行任何更改。同样,我不是编译器专家,但我认为扩展方法上下文中的"this"关键字是允许语法糖,允许我们使用这些方法,就好像它们属于对象一样。

.NET Framework 要求每个方法都存在于程序集内的类中。 一种语言可以允许在没有显式指定的封闭类的情况下声明方法或字段,将所有此类方法放在程序集Fnord中,放入名为 Fnord_TopLevelDefault 的类中,然后在执行方法查找时搜索所有程序集的Fnord_TopLevelDefault类;但是,必须扩展 CLS 规范才能使此功能顺利适用于混合语言项目。 与扩展方法一样,如果 CLS 不承认,这种行为可能是符合 CLS 的,因为不使用此类功能的语言中的代码可以使用"自由浮动"方法,Foo汇编Fnord通过将其拼写Fnord_TopLevelDefault.Foo,但这会有点丑陋。

一个更有趣的问题是,允许从任意类调用扩展Foo方法而不要求对该类的清晰可见引用在多大程度上比允许同样调用非扩展静态方法的危害小。 我不认为Math.Sqrt(x)真的比Sqrt更具可读性;即使不想在任何地方导入Math,至少能够在本地这样做在某些情况下也可以大大提高代码的可读性。

它们可以在内部引用其他静态类成员。

您不仅应该考虑消费者端方面,还应该考虑代码维护方面。

尽管智能感知不区分所有者类,但信息仍然通过工具提示和添加到 IDE 中的任何生产力工具提供。这可以很容易地用于为方法提供一些上下文,否则这将是一个平面(有时很长)的列表。

消费者方面,底线,我认为这并不重要。