最佳实践:C#扩展方法命名空间和推广扩展方法

44

我知道已经有一个帖子,几乎描述了相同的内容,但我认为我的略有不同。

我想知道的是你如何组织你的扩展方法来分配命名空间。目前,对于我们框架中的扩展方法,我使用以下命名空间模式:

  • MyCompany.Web.Utils

在其中我有扩展方法类。这对我来说很好,缺点是扩展程序员不能立即看到扩展器。考虑这样一个情况,我有一个StringExtender类,提供一个非常方便的扩展方法"In"来扩展String对象。如果把扩展方法放在上述命名空间中,除非他们显式包含其命名空间,否则我们的程序员将无法看到扩展方法。相反,如果我将扩展方法放在System命名空间中,每个人都能立即看到它,但我已经读到这是不好的实践方式

所以我的问题是,你如何推广你的扩展方法,使它们被开发人员使用。

10个回答

44

我们将所有扩展方法放置在它们自己的命名空间中Company.Common.Extensions。这样,如果您有我们的任何一种扩展方法,您就拥有了它们全部。此外,在我的工作室里,我们不必担心开发人员不知道扩展方法。我反而担心扩展方法过载! :)


2
(+1) 我同意,我们使用命名约定,在末尾添加扩展名。 - Johan Leino
这基本上就是我正在做的事情。所以我想继续这么做是最好的方式。谢谢。 - Juri
关于扩展重载的+1,但至少你有一个公共命名空间,因此发现可用的内容非常容易。 - Ralph Willgoss
我曾担心如果您在同一解决方案中有多个项目,这种方法可能无法正常工作,因为每个解决方案都需要自己的命名空间,但事实并非如此。每个日常项目都可以共享扩展方法的相同命名空间。 - sparebytes

10

这里的问题不在于命名空间的命名,而在于你们的开发人员缺乏文档和教育。

将它们放在任何有意义的命名空间中,编写一个维基文章记录所有扩展方法,然后向开发人员发送一封带有维基文章链接的电子邮件。


是的,那是我的另一个选择。在软件开发团队中,缺乏沟通常常是一个问题。我们已经在建立一个维基的过程中,但由于时间紧迫,而且管理层对这种活动不予支持,所以这通常是相当困难的。我想人们知道我在说什么。 - Juri
3
我能理解你的感受。有时候,我发现先去做这些事情,让人们开始使用它们,然后再告诉管理层会更好 :) - Winston Smith
3
我不再参与这个项目,也无法访问代码库或维基。请您停止给我发送这些邮件,谢谢。 - jwg

7

这不是一个命名空间问题,而是一个通信问题。

如果这些方法有用,你需要向开发人员传达这一点,并相应地采取他们的反馈意见(具有适当的判断水平)。

将任何东西放入系统命名空间中会导致灾难和混乱。您唯一想要这样做的时候是将功能“回退”到旧框架中,那么您可能不应该自己这样做,而应该使用类似 LinqBridge 的东西来实现。

谨慎地希望将所有扩展都放入一个命名空间中,除非它们确实广泛地一起使用。如果通过智能感知被轰炸了所有内容和厨房水槽,一些开发人员可能会感到困惑。

通常情况下,将命名空间保留为公司名称是明智的,以避免混淆。


小心将所有扩展都放入一个命名空间,除非它们真的广泛地一起使用。我们有很少的扩展方法,并且也尽量保持它们的规模较小。所以这应该不会成为一个问题。 - Juri

3

@Juri- 如果你想一想,这与开发人员知道.NET框架中存在X类的问题是相同的。关键在于所有团队成员都使用正确的类,无论是扩展方法还是其他帮助程序。

正如JP所说,我经常看到扩展方法放在名为Extensions的某种子文件夹中。希望当您声明使用my.company.web.utils命名空间时,实际上是帕斯卡式命名法?

即使您将它们放在合适的位置,也不能保证其他开发人员会100%使用它们。


是的,名称采用帕斯卡命名法...在发布时没有注意到这一点 :) - Juri

3

假设您使用Visual Studio,一种方法是创建自定义类模板(或修改默认模板),以便每当开发人员创建新的类文件时,它自动具有使用您的命名空间的语句。请参见定制Visual Studio 2005模板以提高编码效率


2
我喜欢ReSharper解决这个问题的方式。
ReSharper会发现所有可用的扩展方法,即使没有相应的usings。 如果不存在using,Intellisense也会显示扩展所在的命名空间,清楚地表明扩展来自哪里,并指示选择它将添加using。(如下例所示。)
当然,只有当前项目可以访问的命名空间,即直接或间接引用的命名空间才会被包括在内。
以下是Intellisense可能显示的两个扩展方法的示例。第一个来自我们已经包含的命名空间。 第二个来自我们尚未包含的命名空间。
  • AddMvc
  • AddEntityFrameworkSqlServer (Microsoft.Extensions.DependencyInjection)
"最初的回答"

2
是的,我认为把扩展方法放在自己公司的命名空间中是最佳实践。把它放在系统命名空间中是一种懒惰的操作。

任何东西放在System或其他常见的命名空间中通常是一个糟糕的决定。划分出自己的命名空间(公司、项目、库等)并使用它。这样正确的命名空间选择本身就是一种代码文档形式。进一步使用子“扩展”命名空间简化未来的工作。 - user2864740

2

我很蠢、懒惰和极简主义,所以我把它们放在与它们扩展的类型相同的命名空间中。通过这种方式,无需额外的使用语句、文档或邮件 (Winston)。


这并不是“懒惰”,因为它为未来的工作做出了贡献。然而,它是“愚蠢”的,因为它使得代码更难以维护,只是为了“节省”一行代码(和一个可能的目录)。特别是对于任何开始污染外部代码使用的公共扩展。"懒惰:让你付出巨大努力来_减少总体能量消耗_.. {并且让你避免无意义的捷径,使得维护代码变得毫无意义。}" - user2864740

0
我们将所有内容放置在相同的命名空间和类中,但是我们使用部分类来保持它们的组织结构。
例如:

ExtensionMethods-String.cs

ExtensionMethods-DataObject.cs

ExtensionMethods-Debug.cs

...等都有部分类...


2
使用部分类作为扩展方法有什么优势?我看到很多人将扩展方法放入.Extensions命名空间中,并根据它们扩展的类来命名类和文件:StringExtension.cs和public static class StringExtensions{}。 - CodeMonkeyKing
@CodeMonkeyKing - 有些扩展方法会被遗忘。当我们使用某个应用程序时,我们根据逻辑功能添加扩展,这通常与.NET类的布局不一致。虽然我也喜欢你的方法。 - makerofthings7

0

你可以通过将扩展方法放在全局命名空间中来实现你想要的功能。这就是我所做的,它们可以在不需要任何using语句的情况下使用。


任何非平凡代码都不应采用这种可导致未来复杂性的策略,特别是如果这些扩展是公开的。突然间,你会转移到另一个项目,或者包含一组不同的程序集和随机扩展方法,例如 string#IsEmpty(this string str) 将会“莫名其妙”地出现或消失。 - user2864740

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接