C#接口的扩展方法命名规范

50
我通常将我的C#接口命名为IThing。 我正在为IThing创建一个扩展方法类,但我不知道该如何命名。 一方面,称其为ThingExtensions似乎意味着它是某个Thing类的扩展类,而不是IThing接口的扩展类。 它还会使扩展类在按字母顺序查看文件时与其扩展的接口分开排序。 另一方面,将其命名为IThingExtensions则看起来像是一个接口本身,而不是一个接口的扩展类。 你有什么建议吗? 编辑:回应一些评论,没有实现IThingThing类。

应该迁移到程序员,因为它不涉及编码问题,而是涉及开发实践(如何命名扩展方法)。 - user456814
来到这里寻找一个明确的获胜答案,实际上并不惊讶没有找到一个... 我被迫点赞你的问题和 Reed 和 Jared 的两个答案! - Andras Zoltan
6个回答

47
我绝对更喜欢名称为ThingExtensions而非IThingExtensions。原因是,对于大多数程序员来说,类型名称前缀的I意味着它是一个接口。这既是一种非常常见的模式,也是.NET设计指南的一部分。
在扩展方法的情况下添加I前缀会破坏这两个假设和已经确立的指南。
基础类库中也有先例。大多数可用于IEnumerable的扩展方法都包含在类型Enumerable中。

3
我正在想象一个名为Thing的类,它实现了IThing接口,因此如果将其命名为ThingExtensions但在IThing上起作用,这将会让人感到困惑。但是,@Sarah Vessels没有明确说明这一点... - Klaus Byskov Pedersen
@klausbyskov:实际上没有一个实现IThing接口的Thing类。我会更新我的问题。 - Sarah Vessels
1
我认为“Extensions”后缀有点消除了这种歧义? - Zar Shardan
我们不能严格地将以"I"开头的对象仅保留给接口。例如:class Integrations,class Interrupts,class InsufficientMemoryException... - Micah Epps

24

个人意见,我会使用IThingExtensions

从可用性角度来看,最终用户永远不会看到这个类 - 他们只包含它的命名空间。如果命名空间与IThing相同,那么无所谓-他们已经有了它。

话虽如此,我认为这些是任何IThing的扩展,使得IThingExtensions最清晰明了。如果你有一个Thing类,把它叫做ThingExtensions可能会让人感到歧义(你是扩展接口还是实现本身?)。

话虽如此,框架采取了非常不同的方法。框架的方法是使用一个名为Thing的类来扩展IThing。例如,参见Enumerable(扩展IEnumerable)和Queryable(扩展IQueryable)。这也是一个非常好的选择。


1
我在我的项目中遵循框架的方法。目前还没有出现任何不良副作用。 - Paul Turner
3
我仍然不喜欢这种做法,因为它违反了类型命名的设计准则。特别是只有当它确实是一个接口时,才使用"I"作为前缀类型名称。详情请参考:http://msdn.microsoft.com/zh-cn/library/ms229040.aspx。 - JaredPar
2
@JaredPar:是的,但不幸的是,设计指南并没有为命名扩展方法类提供任何指导——它们只是谈论何时使用它们(即:http://blogs.msdn.com/brada/archive/2009/01/12/framework-design-guidelines-extension-methods.aspx)。我更喜欢使用Thing,除非你正在创建一个Thing类——在这种情况下,ThingExtensions会让人感到困惑...希望在某个时候会有官方指导。 - Reed Copsey
@JaredPar System.Web.Mvc.Html 有很多东西,但名称并没有表明扩展的类。相反,它通过主题将扩展方法分组,例如FormExtensionsChildActionExtensions。还有位于 System.Web.MvcAjaxRequestExtensions 扩展了 HttpRequestBase。然而,这些都不存在于上面的评论添加时。 - Tsahi Asher
Roslyn 拥有 ISymbolExtensions 类: https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.isymbolextensions?view=roslyn-dotnet - Denis535
显示剩余5条评论

4
我认识的大多数程序员将他们应用程序中的所有扩展方法放在一个名为 ExtensionMethods(或类似名称)的静态类中,而不管扩展修改的是哪个类,然后将此类放入他们的主程序命名空间中。
他们的理由是,如果将扩展方法放在与其修改的类相同的命名空间中,可能会将该方法与实际类的方法混淆,这表明该扩展方法是原始功能的一部分,而事实并非如此。
当然,对此并没有普遍共识。请参见此处:How do you manage the namespaces of your extension methods?

3
我采用了略微不同的方法,而不是使用Extension作为后缀,而是将命名策略反转,以Extend作为包含扩展方法的类的前缀;我的理由如下:
  • 正如Reed Copsey's answer所指出的那样,很少有客户端代码直接引用包含类,因为扩展方法的关键点是模拟引用方法。他们不会看到这些类,所以你的类命名约定选择对代码影响微乎其微。
  • 这些类必须是static,因此您永远不会实例化它们。因此,就命名而言,你永远不会遇到new ExtendThing()的语义怪异问题。
  • 所有的Extend*类都可以根据文件名进行视觉分组排序。
  • 关于你的问题,没有任何接口命名前缀混淆; 你可以同时拥有ExtendThingExtendIThing,并且(在我看来)它们的意图和目标是清晰的。

namespace MyCompany.Extensions
{
    public static class ExtendObject { }

    public static class ExtendDateTime { }

    public static class ExtendIEnumerable { }
}

3

我建议将其放在一个名为Extensions的文件夹(和命名空间)中,并将其命名为IThingExtensions


2

我不知道有关于这个的任何标准惯例。我会使用ThingExtensions或ThingInterfaceExtensions。我会避免使用IThingExtensions,就像你提到的那样。


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