库的C#名称空间和类命名约定


26

我正在用C#构建带有各种小型实用程序函数的库,并尝试确定名称空间和类命名约定。我目前的组织是这样的:

Company
Company.TextUtils
    public class TextUtils {...}
Company.MathsUtils
    public class MathsUtils {...}
    public class ArbitraryPrecisionNumber {...}
    public class MathsNotation {...}
Company.SIUnits
    public enum SISuffixes {...}
    public class SIUnits {...}

这是组织名称空间和类的好方法,还是有更好的方法?特别是,在名称空间和类名称(例如,Company.TextUtils名称空间和TextUtils类)中具有相同的名称似乎只是重复,这表明该方案可能会更好。



5
Microsoft准则建议为枚举使用单数名称(因此SISuffix而不是SISuffixes),我认为单数更好。 Suffix.A 读为 “后缀A”。同样,我通常避免在层次结构中的某个层次上重复名称。也就是说,不是Company.SIUnits.SISuffixes,我的偏向Company.SI.SuffixCompany.SI.Unit
哈里森潘恩

Answers:


9

很难确定您的命名策略与其余代码的隔离程度。

命名空间应该给出一些适合于代码库广泛结构的想法,而类名通常会描述该名称空间在该区域代表的功能或概念。

抛开警告,在您的特定示例中,如果您可能有更多的“ Util”类型类,我会考虑将它们放在Company.Utils.Maths等下。这样,如果您需要添加多个实用程序领域共有的功能,则已经一个自然的位置。


1
这听起来像一个好主意。不要过多担心,只需将其全部放入“ Company.Util”即可。
用户

30

有一个很好的文档,其中包含许多规则,您必须遵循这些规则才能与Microsoft:Framework Design Guidelines保持一致

您应该更改的一件事:不要将类命名为它们的名称空间。这将导致编译器混淆。只是不要。为名称空间的任一类找到一个更好的名称。


3
到名称空间指南的直接链接:msdn.microsoft.com/en-us/library/ms229026
v=vs.110).aspx

1
无论是巧合还是非巧合,这也是一本伟大的书籍的同名书,也由参与创建DotNet框架的Microsoft员工撰写,并附有关于他们做对了什么以及哪里做错了什么的几点评论。值得一读:amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/…–
Machado

@nvoigt,能否请您编辑您的答案,以从我们的朋友Pagotti提供的链接中添加引号:“ 请勿对名称空间和该名称空间中的类型使用相同的名称。例如,请勿将Debug作为名称空间名称使用,然后在同一名称空间中提供一个名为Debug的类。一些编译器要求此类类型是完全合格的。”
马查多

2
注意:有时产品名称比使用公司名称更好。在一些公司被收购的情况下,我们不得不全盘产生新的名称空间并重新发布。我认为这是次要的,但想指出。
乔恩·雷诺

1
Microsoft的框架设计指南非常有问题,包含有关.NET工作原理的虚假陈述,并且Microsoft本身常常不遵循。它们的命名准则很好,但是我会避免将总体准则与“应该遵循”它们的声明联系起来。
卡尔·莱斯

6

自从我使用C#或.NET生态系统以来已经有一段时间了,所以我不能说当前推荐的最佳实践是什么。我建议像这样更改您的名字:

Company
Company.Text
    public class TextUtils {...}
Company.Math
    public class MathUtils {...}
    public class ArbitraryPrecisionNumber {...}
    public class MathsNotation {...}
Company.SI
    public enum SISuffixes {...}
    public class SIUnits {...}

我在这里所做的是从名称空间名称中删除“ Utils”。我认为“ Util”不应位于名称空间中,因为该Company.Text名称空间有一天可能包含不是文本实用程序类的类。Company.Math名称空间已经包含了ArbitraryPrecisionNumber似乎不是“实用程序” 的名称空间。

从名称空间中删除“ Util”还可以消除由两个具有相同名称的事物引起的混淆(如罗伯特的回答中所述:https : //softwareengineering.stackexchange.com/a/340440/13156

您可以组织代码的另一种方式:

Company
Company.Util
    public class TextUtils {...}
    public class MathUtils {...}
Company.Math
    public class ArbitraryPrecisionNumber {...}
    public class MathsNotation {...}
Company.SI
    public enum SISuffixes {...}
    public class SIUnits {...}

在这种情况下,所有实用程序类都位于同一名称空间中。Company.Text因为只有一个实用程序类,所以没有更多的名称空间。

就个人而言,我发现第一种选择更加清晰。


4

为名称空间及其内部的类使用相同的名称是有问题的。

  • 如果命名空间包含多个类,为什么还要在其中放置其他类?感觉不对,因为名称空间名称的目的是描述其中的所有类,而不仅仅是一个类。举例来说,如果你有JsonSerializationBinarySerializationXmlSerialization在命名空间中的类,会是有意义的名字命名空间XmlSerialization

    通常发生的情况是,由于从现有名称空间中提取了一个类,或者由于多个类之间的合并或其他重组,您发现自己拥有一个包含主要类的名称空间;逐渐地,将次要课程放置在这里,因为它们与原始课程略有相关。例如,一个名称空间LogParser可能包含一个类LogParser,然后有人放置LogConverter,因为它与解析器,然后LogSearcher等等非常相关。这里的问题是名称空间的名称没有更改:LogConverter添加后,名称应该已更改为LogsProcessing或简单地说Logs

  • 如果名称空间仅包含一个类,则可能是代码组织内出现问题的迹象。

    虽然我已经多次看到具有适当SOLID原则的单个类与代码库中的其他任何类都有很大不同,因此被放置在专用名称空间中的情况,但这种情况很少见。通常,这表明存在问题。同样,没有什么可以阻止您的类包含单个方法,但是,此类类通常会指示问题。

    即使您的名称空间仅包含一个类,在命名该类时通常也可以有一种更具体的方法,而在命名空间时则可以采用一种更通用的方法。想象一下一个应用程序,该应用程序除其他外应在给定时刻将以ABC格式编写的文件转换为DEF格式。转换不需要对业务对象进行任何反序列化/反序列化,它是通过应用一堆正则表达式来完成的,这些正则表达式足够短,可以放在转换类本身中,称为AbcToDefConverter。所有的转换逻辑在大约十种相互依赖的方法中花费了大约80 LLOC,这似乎是绝对不需要拆分现有类或创建其他类的情况。由于应用程序的其余部分与转换无关,因此该类不能与现有命名空间中的其他类分组。因此,我们创建了一个名为的命名空间AbcToDefConverter。虽然这并没有内在的错误,但也可以使用更通用的名称,例如Converters。在诸如Python之类的语言中,首选使用较短的名称并引发重复,甚至可能变成converters.Abc_To_Def

因此,对于名称空间请不要对它们使用的名称使用不同的名称。类的名称应指示该类在做什么,而名称空间的名称应突出显示放置在其内的所有类中的共同点。


顺便说一句,实用程序类本质上是错误的:与其包含某些特定的东西(例如任意精度算术),不如包含其他类中未找到的所有东西。就像Miscellaneous在桌面上的目录一样,这真是不好的命名,这表明缺乏组织。

命名的存在是有原因的:当您以后需要查找内容时,可以使您的生活更轻松。您知道,如果需要绘制图表,可以尝试搜索“图表”或“图表”。当您需要更改应用程序生成发票的方式时,可以搜索“发票[e / ing]”或“账单”。同样,尝试想象一下您会对自己说:“嗯,此功能可能应该在其他地方找到”。我不能

看一下.NET Framework。这些类中的大多数不是实用程序类吗?我的意思是,它们与业务领域无关。如果我在金融应用程序,电子商务网站或下一代教育平台上工作,那么对XML进行序列化或读取文件,执行SQL查询或执行交易都是实用程序。但是,它们不被称为UtilitySerializationUtilityTransaction,并且它们不在Utility名称空间中。它们具有适当的名称,这使得(在需要时可以轻松地感谢.NET开发人员!)在我需要它们时可以找到它们。

对于通常在应用程序中重复使用类,也是如此。它们不是实用程序类。它们是做某些事情的类,而他们做的事情实际上应该是这些类的名称。

假设您创建了一些处理单位和单位换算的代码。您可以为其命名,Utility并受到同事的憎恨;或者您可以命名为UnitsUnitsConversion


7
“公用事业课本质上是错误的”。有趣。您为诸如Math函数实用程序类之类的东西提出什么解决方案?要使用基本算术运算符以外的功能,是否真的需要Math对象的实例
FrustratedWithFormsDesigner

1
我同意您的意见,但是您有什么建议呢?
用户


4
我推迟了最长的时间来创建“ utils”库,但最终您只需要让步。另一种方法是让DLL包含大约3行代码,这很麻烦(这让我想起了node.js的依赖是一团糟) ),或将实用程序方法复制并粘贴到可能需要它们的每个类中(以避免使用“随机方法集合”类)。IMO最终是必要的邪恶。
Matti Virkkunen

3
@FrustratedWithFormsDesigner:简单... Math?我看不到Utility在所有内容中添加后缀如何使我们的生活更轻松。使用.NET的System.Math.Min()方法时,您真的更喜欢编写SystemUtility.MathUtility.Min()吗?在所有情况下,我都认真编辑了答案,因此现在应该更清楚了。
Arseni Mourzenko '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.