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

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

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

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

在这个项目中,有几个文件夹与命名空间部分相匹配:

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

在同一个项目中,是另一个流氓文件夹

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

有一些像这样的文件夹是为了“组织便利性”而创建的。

我的问题是:什么是标准?在类库中,文件夹通常与命名空间结构相匹配还是混合包?

0
注意:如果命名空间与文件夹层次结构不匹配,ReSharper会发出抱怨。
额外 作者 Fred,

6 答案

是的,他们应该,只会导致混淆,否则。

0
额外

我会说是的。

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

其次,VS将生成新的类,这些类使用与其父文件夹结构相同的名称空间在文件夹中创建。如果你决定游泳,那么在添加新文件时,这将只是每天进行的一项管道工作。

当然,这并不是说对xs文件夹/命名空间层次结构的深度应该保守。

0
额外

我认为.NET中的标准是在可能的情况下尽量做到这一点,但不要创造出不必要的深层结构,只是坚持它作为一个硬性规则。我的项目中没有任何一个项目在100%的时间内遵循命名空间==结构规则,有时它只是更清晰/更好地脱离这些规则。

在Java中,你没有选择。我会称之为理论上有效的经典案例与实践中的作品。

0
额外
我会说“当你真的想要在自己的命名空间中做某件事时做到这一点”。这应该是一个有意识的决定。如果您的项目正确隔离,它应该是每个项目的一个名称空间。如果你的类位于命名空间中,它应该位于具有该命名空间的文件夹中,或者至少与命名空间至少具有特定关系的子文件夹位置。像Car.Ford.Fusion这样的类(如果Car.Ford是你唯一的名字空间)应该放在Car / Ford或像Car / Ford / Sedans这样的更深的文件夹中,这样该文件夹至少至少如同命名空间一样具体。只是不要把它放在Car / Unrelated / Ford;这是令人困惑的。
额外 作者 Triynko,
为什么这不是被接受的答案?它应该是。
额外 作者 Luty,

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

这些课程将更容易找到,而且这应该是足够好的原因。

我们遵循的规则是:

  • 项目/程序集名称与根名称空间相同,除了.dll结尾
  • 以外
  • 只有上述规则的例外情况是具有.Core结尾的项目,.Core会被剥离
  • 文件夹等于命名空间
  • 每个文件(类,结构,枚举,委托等)的一种类型可以很容易地找到正确的文件
0
额外
+1 for “只有上述规则的例外是一个.Core结尾的项目,.Core会被剥离”。我有一个 MyProject.Core.dll 程序集,所有类都以 MyProject.Core 开头。剥离 .Core 后缀更有意义。
额外 作者 Luiz Damim,
我可能会添加的另一个例外是例外。例外已经以'Exception'作为后缀,所以额外的命名空间是多余的。它也可能会让部分命名空间与单词Exception混乱(可能导致混淆System.Exception)。但是,将它们组织成文件夹非常有用。
额外 作者 phillipwei,

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

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

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

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

没有。

我已经在小型和大型项目上尝试了这两种方法,包括单个(我)和一组开发人员。

我发现最简单和最有效的方法是每个项目都有一个名称空间,并且所有类都进入该名称空间。然后您可以自由地将类文件放入您想要的任何项目文件夹中。因为只有一个命名空间,所以不必在文件顶部添加使用语句。

将源文件组织到文件夹中非常重要,我认为这是所有文件夹都应该使用的。要求这些文件夹也映射到名称空间是不必要的,会创建更多的工作,并且我发现实际上对组织有害,因为增加的负担会导致组织的混乱。

以此FxCop警告为例:

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

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

查找文件

被接受的答案是:“这些课程会更容易找到,而且这应该是足够好的原因。”

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

在任何情况下,当您无法从名称空间确定类文件位于哪个文件夹时,可以使用“转到定义”或Visual Studio中的搜索解决方案资源管理器框来查找它。这在我看来并不是一个真正的大问题。我不会花费我的开发时间的0.1%来查找文件来证明优化它的问题。

名称冲突

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

  • class Project1.Image.Rectangle
  • class Project1.Window.Rectangle

有可能遇到一个源文件需要包含这两个名称空间的问题。现在,您必须在该文件的每个地方写出完整的命名空间:

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

或者讨论一些令人讨厌的使用陈述:

using Rectangle = Project1.Window.Rectangle;

在你的项目中只有一个命名空间,你不得不想出另外一个命名空间,我会提出更多描述性的名字,例如:

  • class Project1.ImageRectangle
  • class Project1.WindowRectangle

而且使用情况在任何地方都是一样的,当文件使用这两种类型时,您不必处理特殊情况。

using statements

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

VS

using Project1;

编写代码时不必一直添加命名空间。这不是真正需要的时间,它是不得不做的时间流逝,只是用很多使用陈述来填充文件 - 为什么?这值得么?

Changing project folder structure

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

使用项目中的单个命名空间,您可以更改项目文件夹结构,但不需要修改任何源文件。

Visual Studio automatically maps the namespace of a new file to the project folder it's created in

Unfortunate, but I find the hassle of correcting the namespace is less than the hassle of dealing with them. Also I've got into the habit of copy pasting an existing file rather than using Add->New.

Intellisense and Object Browser

在我看来,在大型项目中使用多个名称空间的最大好处是在查看名称空间层次结构中显示类的任何工具中的类时都具有额外的组织结构。即使是文件。显然,在项目中只有一个名称空间会导致所有类都显示在一个列表中,而不是分为多个类别。然而,我个人从来没有因为缺乏这个而陷入困境或延迟,所以我没有发现证明多个命名空间足够大的好处。

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

0
额外
这是我见过的最好的建议之一。命名空间仅用于冲突解决,而不是组织类。仅在使用命名空间的地方使用命名空间,比如您希望与其他可能使用项目的项目发生命名冲突,允许使用某些命名空间或使用语句排除。可怕的是没有一个具有3或4个或更多的常用命名空间的项目,因为它总是导致需要添加和添加以及添加的使用语句的荒谬数量。打破你的项目。
额外 作者 Triynko,
命名空间最大的一点是避免命名冲突和模糊,对吗?我同意使用报表点100%。有时,当你拥有数十亿个命名空间/使用时,引入新的开发者只是纯粹的疯狂。扩展方法是IDE通常不太有用的地方的一个例子。将所有文件(或甚至是太多文件)放在单个文件夹中以避免打破命名空间/文件夹规则同样是疯狂的。
额外 作者 jocull,
我同意@BentOnCoding。另一件事你的帖子也表明,输入命名空间通常需要在不同命名空间中具有相同名称的类的详细程度,但是C#可以使用Foo作为Bar 伪指令来优雅地使用
额外 作者 Evin Ugur,
诚实地说,这是我听到的最噩梦的解决方案之一。如果你在小型世界项目上工作,那么这个建议很有用,但想象你有1000个以上的.cs文件。这会造成很多问题,我不知道从哪里开始。
额外 作者 BentOnCoding,
@WeylandYutani我知道我迟到了,但我需要提及的是:可以使用Go To Definition或Visual Studio中的搜索解决方案资源管理器框找到它并非总是如此。尝试它许多继承和接口...找到正确的文件好运。
额外 作者 Emmanuel M.,
+1进行思考。我不认为我已准备好将每个项目的命名空间减少到一个,但是在处理一个大型框架之后,我正在探索减少命名空间的数量,以减少使用语句的数量并帮助发现扩展方法。我认为这个答案提供了一些值得思考的食物。谢谢。
额外 作者 Lee Gunn,
“但是想象一下你有1000多个.cs文件”。我曾用一个名称空间来处理这种大小的项目。没关系。你认为会发生什么灾难?
额外 作者 Weyland Yutani,
我提到过,我不认为它优雅,我认为这是一个黑客
额外 作者 Weyland Yutani,
尽管你的所有有效积分都会丢失,因为视觉愚蠢选择了一个模式和一个默认值。更糟糕的是,它们遵循虚拟文件结构,所以即使是真正的文件夹也不是两个观点都很糟糕的命名空间。
额外 作者 Tommy Holman,