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

Should the folders in a solution match the namespace?

提问人: 提问时间:8/7/2008 最后编辑:Marius Bancila 更新时间:7/15/2018 访问量:62408

问:

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

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

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

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

  • 文件夹在命名空间中包含类VehiclesMyCompany.Project.Section.Vehicles
  • 文件夹在命名空间中包含类ClothingMyCompany.Project.Section.Clothing
  • 等。

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

  • 文件夹在命名空间中包含类BusinessObjectsMyCompany.Project.Section

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

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

C# .NET 命名空间

评论

11赞 Fred 3/14/2016
注意:如果命名空间与文件夹层次结构不匹配,ReSharper会抱怨。
0赞 Alain 3/3/2023
如果您将每个文件夹的“Namespace Provider”文件夹属性设置为“False”,则ReSharper不会抱怨,而该文件夹不打算引入新的命名空间。

答:

3赞 Dan 8/7/2008 #1

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

评论

2赞 Piotr Golacki 8/16/2022
有证据或参考资料支持吗?
6赞 Ishmaeel 8/7/2008 #2

我会说是的。

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

其次,VS 将生成您在文件夹中创建的新类,这些类具有与其父文件夹结构相同的命名空间。如果您决定与此相反,那么在添加新文件时,每天要做的只是一项管道工作。

当然,不言而喻,对于 xis 文件夹/命名空间层次结构的深度应该保守。

37赞 Karl Seguin 8/7/2008 #3

我认为 .NET 中的标准是在可能的情况下尝试这样做,但不要仅仅为了遵守它作为硬性规则而创建不必要的深层结构。我没有一个项目 100% 遵循命名空间 == 结构规则,有时打破这些规则会更干净/更好。

在 Java 中,你别无选择。我称之为理论上有效的方法与实践中有效的经典案例。

评论

2赞 Triynko 5/3/2017
我会说“当你真的希望某些东西在它自己的命名空间中时,就去做”。这应该是一个有意识的决定。如果项目已正确隔离,则每个项目应有一个命名空间。如果类位于命名空间中,则它应该位于具有该命名空间的文件夹中,或者至少与命名空间一样具体的子文件夹位置中。像 Car.Ford.Fusion 这样的类(如果 Car.Ford 是你唯一的命名空间)应该位于类似 Car/Ford 的文件夹中,或者像 Car/Ford/Sedans 这样的更深层次的文件夹中,这样文件夹至少与命名空间一样具体。只是不要把它放在 Car/Unrelated/Ford 中;这令人困惑。
89赞 Lasse V. Karlsen 8/7/2008 #4

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

这些课程将更容易找到,仅此一项就应该足够好了。

我们遵循的规则是:

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

评论

1赞 Luiz Damim 4/25/2013
+1 表示“上述规则的唯一例外是具有 .核心结尾,.核心被剥离“单独。我有一个程序集,所有类都以 .去掉后缀更有意义。MyProject.Core.dllMyProject.Core.Core
3赞 phillipwei 1/14/2015
我可能会添加的另一个例外是例外。异常已以“Exception”为后缀,因此额外的命名空间是多余的。命名空间的一部分带有 Exception 一词(可能导致混淆 System.Exception)也会变得混乱。但是,将它们组织到文件夹中非常有帮助。
0赞 2/28/2023
我将为每个文件的一个类型添加一个个人例外(虽然从技术上讲仍然只有一种类型)。例如。和。SomeBaseClassSomeBaseClass<T> : SomeBaseClass
26赞 Jay Bazuzi 9/11/2008 #5

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

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

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

// ----- Foo.Bar.cs
partial class Foo
{
    class Bar
    {
        // Foo.Bar implementation here
    }
}
95赞 Weyland Yutani 3/25/2015 #6

不。

我在小型和大型项目上都尝试过这两种方法,无论是单个(我)还是一个开发人员团队。

我发现最简单和最有效的方法是为每个项目设置一个命名空间,并且所有类都进入该命名空间。然后,您可以自由地将类文件放入所需的任何项目文件夹中。一直以来在文件顶部添加 using 语句不会造成麻烦,因为只有一个命名空间。

将源文件组织到文件夹中很重要,在我看来,这就是所有文件夹都应该使用的用途。要求这些文件夹也映射到命名空间是不必要的,会产生更多的工作,而且我发现实际上对组织有害,因为增加的负担会鼓励混乱。

以此 FxCop 警告为例:

CA1020:避免使用类型较少的命名空间 原因:全局命名空间以外的命名空间包含的类型
少于 5 种 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 语句

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 语句填充文件 - 为了什么?值得吗?

更改项目文件夹结构

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

使用项目中的单个命名空间,您可以根据需要更改项目文件夹结构,而无需修改任何源文件本身。

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

很不幸,但我发现纠正命名空间的麻烦比处理它们的麻烦要少。此外,我还养成了复制粘贴现有文件而不是使用“添加>”的习惯。

智能感知和对象浏览器

在我看来,在大型项目中使用多个命名空间的最大好处是,在任何在命名空间层次结构中显示类的工具中查看类时,都有额外的组织。甚至文档。显然,项目中只有一个命名空间会导致所有类都显示在单个列表中,而不是分成类别。然而,就我个人而言,我从来没有因为缺乏这一点而被难倒或延迟,所以我认为它的好处不足以证明多个命名空间的合理性。

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

评论

58赞 BentOnCoding 4/8/2015
老实说,这是我听到的最噩梦般的解决方案之一。如果你从事小型hello world项目,那么这个建议是有效的,但假设你有1000+个.cs文件。这会导致很多问题,我不知道从哪里开始。
20赞 Weyland Yutani 4/14/2015
“但想象一下你有 1000+ .cs 文件”。我曾在具有单个命名空间的这种规模的项目中工作过。没事的。你认为会发生什么灾难?
25赞 Lee Gunn 4/27/2015
+1 思考。我不认为我已经准备好将我的命名空间减少到每个项目一个,但是在处理了一个大型框架之后,我正在探索减少命名空间的数量,以减少 using 语句的数量并帮助扩展方法的可发现性。我认为这个答案值得深思。谢谢。
20赞 Triynko 5/3/2017
这是我见过的最好的建议之一。命名空间仅用于解决冲突,而不是组织类。仅在有意义的情况下才使用命名空间,例如,您预计与可能正在使用您的项目的其他项目发生命名冲突,允许使用 using 语句包含或排除某些命名空间。有一个经常使用的 3 个或 4 个或更多命名空间的项目是很糟糕的,因为它总是导致你需要添加和添加以及添加和添加的 using 语句数量多得离谱。将您的项目分解。
9赞 Steve Vermeulen 9/23/2019
相关:medium.com/@steve_verm/...
1赞 user1451111 7/15/2018 #7

标准是什么?

没有官方标准,但传统上文件夹到命名空间的映射模式使用最广泛。

在类库中,文件夹通常与命名空间匹配 结构还是混合包?

是的,在大多数类库中,文件夹与命名空间匹配,以便于组织。