解决方案中的文件夹是否应与名称空间匹配?


129

解决方案中的文件夹是否应与名称空间匹配?

在我的一个团队项目中,我们有一个类库,该类库在项目中包含许多子文件夹。

项目名称和命名空间:MyCompany.Project.Section

在此项目中,有几个与“名称空间”部分匹配的文件夹:

  • 文件夹VehiclesMyCompany.Project.Section.Vehicles名称空间中具有类
  • 文件夹ClothingMyCompany.Project.Section.Clothing名称空间中具有类
  • 等等

在同一项目中,是另一个恶意文件夹

  • 文件夹BusinessObjectsMyCompany.Project.Section名称空间中具有类

在某些情况下,为了“组织上的方便”而制作文件夹。

我的问题是:什么标准?在类库中,文件夹通常匹配名称空间结构吗?还是混合在一起?


9
注意:如果名称空间与文件夹层次结构不匹配,ReSharper将抱怨。
Fred

Answers:


77

另外,请注意,如果您使用内置模板将类添加到文件夹,则默认情况下会将其放在反映文件夹层次结构的命名空间中。

这些类将更容易找到,仅凭其应是足够好的理由。

我们遵循的规则是:

  • 项目/程序集名称与根名称空间相同,但.dll结尾
  • 上面规则的唯一例外是一个以.Core结尾的项目,.Core被剥离了
  • 文件夹等于名称空间
  • 每个文件一种类型(类,结构,枚举,委托等)使查找正确的文件变得容易

1
对于“仅上述规则的例外是带有.Core结尾的项目,.Core被剥夺”的+1。我有一个MyProject.Core.dll大会,所有课程都从开始MyProject.Core。删除.Core后缀更加有意义。
Luiz Damim

2
我可能要添加的另一个例外是“例外”。异常已经带有“ Exception”后缀,因此额外的名称空间是多余的。如果名称空间的一部分带有Exception一词,也会变得混乱(可能导致System.Exception混淆)。但是,将它们组织到文件夹中非常有帮助。
phillipwei

55

没有。

我已经在小型项目和大型项目中尝试了这两种方法,并且都是由一个(我)和一个开发人员团队来完成的。

我发现最简单,最有效的方法是每个项目有一个名称空间,所有类都进入该名称空间。然后,您可以将类文件放到所需的任何项目文件夹中。始终在文件顶部添加using语句没有任何麻烦,因为只有一个名称空间。

将源文件组织到文件夹中很重要,我认为应使用所有文件夹。不需要这些文件夹也映射到名称空间是不必要的,需要做更多的工作,而且我发现这实际上对组织有害,因为增加的负担鼓励混乱。

以以下FxCop警告为例:

CA1020:避免名称空间类型少的
原因:全局名称空间以外的名称空间包含的类型少于五种 https://msdn.microsoft.com/en-gb/library/ms182130.aspx

此警告鼓励将新文件转储到通用的Project.General文件夹中,甚至转储到项目根目录中,直到您有四个类似的类来证明创建新文件夹的合理性为止。那会发生吗?

查找文件

公认的答案是:“这些班级将更容易找到,仅凭这些就足够了。”

我怀疑答案是指项目中有多个名称空间,这些名称空间不映射到文件夹结构,而不是我建议的是具有单个名称空间的项目。

在任何情况下,虽然无法从名称空间确定类文件所在的文件夹,都可以使用“转到定义”或Visual Studio中的搜索解决方案资源管理器框找到它。我认为这也不是什么大问题。在寻找文件以证明对其进行优化的问题上,我什至没有花费我的开发时间的0.1%。

名称冲突

确保创建多个名称空间可以使项目具有两个具有相同名称的类。但这真的是一件好事吗?禁止这种可能性可能更容易吗?允许两个具有相同名称的类会创建一个更复杂的情况,其中90%的情况下事物以某种方式工作,然后突然发现您有一个特殊情况。假设您在单独的命名空间中定义了两个Rectangle类:

  • 类Project1.Image.Rectangle
  • 类Project1.Window.Rectangle

可能会遇到一个问题,即源文件需要同时包含两个名称空间。现在,您必须在该文件的所有位置写出完整的名称空间:

var rectangle = new Project1.Window.Rectangle();

或者用一些讨厌的using语句弄乱:

using Rectangle = Project1.Window.Rectangle;

在项目中只有一个名称空间时,您不得不提出不同的名称,而我想用更具描述性的名称命名,如下所示:

  • 类Project1.ImageRectangle
  • 类Project1.WindowRectangle

而且用法在每个地方都是相同的,当文件使用两种类型时,您不必处理特殊情况。

使用语句

using Project1.General;  
using Project1.Image;  
using Project1.Window;  
using Project1.Window.Controls;  
using Project1.Shapes;  
using Project1.Input;  
using Project1.Data;  

using Project1;

无需在编写代码时始终添加名称空间的简便性。这不是真正花费的时间,而是必须要做的只是使用大量的using语句填充文件的流程中的中断-为什么?这值得么?

更改项目文件夹结构

如果将文件夹映射到名称空间,则项目文件夹路径将有效地硬编码到每个源文件中。这意味着项目中文件或文件夹的任何重命名或移动都需要更改实际的文件内容。该文件夹中文件的名称空间声明以及在引用该文件夹中的类的其他文件中使用语句。尽管更改本身对工具来说是微不足道的,但通常会导致大型提交,其中包括许多文件甚至其类都没有更改。

使用项目中的单个名称空间,您可以更改项目文件夹的结构,但是无需修改任何源文件本身。

Visual Studio会自动将新文件的名称空间映射到在其中创建的项目文件夹

不幸的是,但是我发现更正命名空间的麻烦少于处理它们的麻烦。另外,我已经习惯于复制粘贴现有文件,而不是使用Add-> New。

智能感知和对象浏览器

我认为在大型项目中使用多个名称空间的最大好处是,在查看任何在名称空间层次结构中显示类的工具中查看类时,都具有额外的组织性。甚至文档。显然,在项目中只有一个名称空间会导致所有类都显示在一个列表中,而不是分为几类。但是,就我个人而言,我从来没有因为缺少它而感到困惑或拖延,所以我发现它没有足够大的好处来证明多个名称空间的合理性。

尽管如果我正在编写一个大型的公共类库,那么我可能会在项目中使用多个名称空间,以使程序集在工具和文档中看起来很整洁。


30
老实说,这是我听过建议的最噩梦的解决方案之一。如果您从事小型hello world项目,则此建议有效,但假设您有1000多个.cs文件。这会导致很多问题,我不知道从哪里开始。
BentOnCoding 2015年

10
“但是假设您有1000多个.cs文件”。我曾在单个名称空间的大型项目中工作过。没关系。您认为会发生什么灾难?
Weyland Yutani 2015年

14
+1思考。我不认为我准备将每个项目的名称空间减少到一个,但是在大型框架上工作后,我正在探索减少名称空间的数量,以减少using语句的数量,并有助于扩展方法的发现。我认为这个答案可以为您提供一些深思的地方。谢谢。
李·耿

3
@WeylandYutani我知道我来晚了,但我需要提一句:you can find it by using Go To Definition or the search solution explorer box in Visual Studio并非总是如此。尝试一下继承和接口方面的问题...祝您找到合适的文件好运。
Emmanuel M.

11
这是我所见过的最好的建议之一。命名空间仅用于解决冲突,而不用于组织类。仅在合理使用命名空间的地方使用命名空间,例如您希望与可能正在使用您的项目的其他项目发生命名冲突的地方,从而允许使用using语句包括或排除某些命名空间。糟糕的是,一个项目经常使用3个或4个或更多个名称空间,因为它总是导致需要添加,添加以及添加和添加的大量使用语句。分开您的项目。
Triynko

31

我认为.NET内的标准是尝试在可能的情况下做到这一点,而不是创建不必要的深层结构,而只是为了坚持这一规则而已。我的项目中没有一个100%的时间遵循命名空间==结构规则,有时它更干净/更好地脱离此类规则。

在Java中,您别无选择。我称这是理论上有效与实践上有效的经典案例。


1
我会说“当您确实希望某些东西位于其自己的名称空间中时,请执行此操作”。这应该是一个有意识的决定。如果您的项目被正确隔离,则每个项目应使用一个名称空间。如果您的类在名称空间中,则应该在具有该名称空间或至少与名称空间相同的子文件夹位置的文件夹中。诸如Car.Ford.Fusion之类的类(如果Car.Ford是您唯一的命名空间)应位于Car / Ford之类的文件夹中,或更深入地位于Car / Ford / Sedans之类的文件夹中,以便该文件夹至少与名称空间一样具体。只是不要将其放在汽车/无关/福特中;令人困惑。
Triynko

25

@lassevk:我同意这些规则,还有一点要补充。

当我有嵌套类时,我仍然将它们拆分开,每个文件一个。像这样:

// ----- Foo.cs
partial class Foo
{
    // Foo implementation here
}

// ----- Foo.Bar.cs
partial class Foo
{
    class Bar
    {
        // Foo.Bar implementation here
    }
}

5

我会说是的。

首先,通过遵循名称空间(例如,当有人通过电子邮件向您发送裸异常调用堆栈时)来查找实际的代码文件会更容易。如果让文件夹与命名空间不同步,那么在大型代码库中查找文件将变得很累人。

其次,VS将在与父文件夹结构相同的名称空间的文件夹中生成您创建的新类。如果您决定不这样做,那么添加新文件时,每天要做的只是一项繁琐的工作。

当然,这毋庸置疑,对于xis文件夹/命名空间层次结构的深入程度,应该保持保守。


4

是的,他们应该这样做,否则只会导致混乱。


2

有什么标准?

没有官方标准,但通常使用最广泛的文件夹到名称空间映射模式。

在类库中,文件夹通常匹配名称空间结构吗?还是混合在一起?

是的,在大多数类库中,文件夹都与名称空间匹配,以简化组织。

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.