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

Posted

技术标签:

【中文标题】最佳实践:C# 扩展方法命名空间和推广扩展方法【英文标题】:Best practices: C# Extension methods namespace and promoting extension methods 【发布时间】:2010-11-16 14:32:52 【问题描述】:

我知道已经存在一个post,描述几乎相同,但我认为我的有点不同。

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

MyCompany.Web.Utils

在里面我有扩展方法类。这对我来说很好,缺点是我们的软件开发人员无法立即看到扩展程序。考虑我有一个 StringExtender 类的情况,它提供了一个非常方便的 extension method "In" 扩展 String 对象。有了上面提到的命名空间的扩展方法,我们的程序员将看不到扩展方法,除非他们明确地包含它的命名空间。相反,如果我将扩展方法放在System 命名空间中,每个人都会立即看到它,但我有read that this is bad practice。

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

【问题讨论】:

【参考方案1】:

我们将它们全部放在自己的命名空间Company.Common.Extensions 中。这样,如果你有我们的任何扩展方法,你就拥有了它们。另外,至少在我的商店,我们不必担心我们的开发人员不知道扩展方法。我有相反的担心,扩展方法过载! :)

【讨论】:

(+1) 我同意,我们使用命名约定,在末尾添加 .extensions。 这基本上就是我已经在做的事情了。所以我想这是继续这样的最佳方式。谢谢 +1 关于扩展重载,但至少你有一个公共命名空间,所以发现可用的内容非常容易。 我担心如果您在同一个解决方案中有多个项目,这将不起作用,因为每个解决方案都需要自己的命名空间,但事实并非如此。每天的项目都可以为扩展方法共享相同的命名空间。【参考方案2】:

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

将它们放在任何有意义的命名空间中,写一篇 wiki 文章记录您的所有扩展方法,然后向您的开发人员发送一封电子邮件,其中包含指向该 wiki 文章的链接。

【讨论】:

是的,那是我的另一个选择。缺乏沟通通常是软件开发团队的一个问题。我们已经在建立一个wiki,但通常非常困难,时间紧迫,而且没有得到管理层对此类活动的支持。我想人们知道我在说什么。 我感受到你的痛苦。有时我发现最好继续做这些事情,让人们使用它们,然后告诉管理层:) 我不再从事这个项目,也无法访问代码库或 wiki。请不要再给我发这些邮件了吗?【参考方案3】:

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

如果这些方法有用,您需要将其传达给开发人员,相反,根据他们的反馈采取行动(具有适当的判断力)。

将任何东西放入 System 命名空间都会导致以后的灾难和混乱。您唯一想做的就是将功能“向后移植”到旧框架中,然后您可能不应该自己做,而应该使用 LinqBridge 之类的东西来做。

要警惕将所有扩展都放到一个命名空间中的愿望,除非它们真的一起广泛有用。一些开发人员可能会在被所有东西和厨房水槽通过智能感知轰炸的情况下发现树木丢失的木材。

在命名空间中保留公司名称通常是明智的,以避免混淆。

【讨论】:

“要警惕将所有扩展都放到一个命名空间中的愿望,除非它们真的一起广泛有用。”我们的扩展方法数量非常有限,并且也在努力使它们保持小规模。所以这应该不会造成问题。【参考方案4】:

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

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

即使你把它们放在一个好的地方,也不能 100% 保证其他开发者会使用它们。

【讨论】:

是的,名字是帕斯卡大小写的……发在这里的时候没注意这个:)【参考方案5】:

假设您使用 Visual Studio,一种方法是创建自定义类模板(或修改默认模板),这样每当开发人员创建新的类文件时,它就会自动在您的命名空间中使用 using 语句。见Customize Visual Studio 2005 Templates for Coding Productivity。

【讨论】:

【参考方案6】:

是的,我认为将扩展方法放在自己的公司命名空间中是最佳实践。放到 System 命名空间是懒惰的操作

【讨论】:

anything 放入 System 或其他 common-anywhere 命名空间通常是一个糟糕的决定。切出您自己的命名空间(公司、项目、库等)并使用它。这种适当的命名空间选择本身就是一种代码文档形式。进一步使用子“扩展”命名空间可以简化未来的工作。【参考方案7】:

我很笨,懒惰和简约,所以我把它们放在与它们扩展的类型相同的命名空间中。这样就不需要额外的 using 声明、文档或通过电子邮件发送有关它们的信息 (Winston)。

【讨论】:

这不是“懒惰”,因为它有助于未来的工作。然而,它是“愚蠢的”,因为为了“保存”一行(可能还有一个目录)而使代码更难维护。对于任何开始污染外部代码使用的公共扩展来说尤其如此。 "Laziness: The quality that makes you go to great effort to reduce overall energy expenditure .. and it makes you avoid meaningless shortcuts that make it needlessly less-lazy to maintain code.".【参考方案8】:

我喜欢 ReSharper 解决这个问题的方式。

ReSharper 会发现任何可用的扩展方法,即使没有相应的使用。如果 using 不存在,Intellisense 还会显示扩展所在的命名空间,明确扩展的来源,表明选择它将添加 使用。 (以下示例。)

当然,仅包括当前项目可访问的命名空间,即直接或间接引用的命名空间。

如果有两种扩展方法,以下是 Intellisense 可能显示的示例。第一个来自我们已经包含的命名空间。第二个来自我们尚未(尚未)包含的命名空间。

AddMvc AddEntityFrameworkSqlServer (Microsoft.Extensions.DependencyInjection)

【讨论】:

【参考方案9】:

我们将所有内容放在同一个命名空间和类中,但是我们使用部分类来保持它们的组织性。

例如:

ExtensionMethods-String.cs

ExtensionMethods-DataObject.cs

ExtensionMethods-Debug.cs

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

【讨论】:

对扩展方法使用分部类有什么好处?我见过很多人将扩展方法放到 .Extensions 命名空间中,并在它们扩展的类之后命名类和文件:StringExtension.cs 和 public static class StringExtensions 。 @CodeMonkeyKing - 一些扩展方法被遗忘了。当我们使用给定的应用程序时,我们会根据逻辑功能添加扩展,这通常与 .NET 类的布局不一致。虽然我也喜欢你的方法【参考方案10】:

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

【讨论】:

任何非平凡代码的可怕的未来并发症诱导策略,特别是如果这些扩展是公共的。突然间,人们会转移到不同的项目,或者包含一组不同的程序集,并且像string#IsEmpty(this string str) 这样的随机扩展方法会“莫名其妙地”出现或消失。

以上是关于最佳实践:C# 扩展方法命名空间和推广扩展方法的主要内容,如果未能解决你的问题,请参考以下文章

C# 数据连接最佳实践?

C# 语法 ( 扩展方法 )

在 .Net 中使用扩展方法的最佳实践是啥?

在PHP中获取上传文件扩展名的最佳方法/实践是啥[重复]

Swift 扩展最佳实践

在 iOS 8 beta 中开发应用扩展的最佳实践