.NET 命名空间

9

我的背景主要是Java开发人员,但最近我一直在做一些.NET的工作。因此,我一直在尝试在家做一些简单的项目,以便更好地使用.NET。我已经能够将我的许多Java经验转化为使用.NET(具体来说是C#),但唯一真正困扰我的是命名空间。

我知道命名空间类似于Java包,但据我所知,主要区别在于Java包使用实际文件夹来显示分离,而在.NET中并不是这样,所有文件都驻留在单个文件夹中,并且命名空间只是在每个类中声明。

我觉得这很奇怪,因为我总是把包看作是组织和分组相关代码的一种方式,使其更容易导航和理解。由于在.NET中它不起作用,随着时间的推移,项目看起来更加拥挤,而且不容易导航。

我错过了什么吗?我必须错过了什么。我应该将事情分成解决方案中的单独项目吗?还是有更好的方法在项目中组织类和文件?

编辑:正如Blair指出的那样,这几乎是相同的问题here

9个回答

11

虽然我不能声称这是最佳实践,但我经常看到文件按照镜像命名空间的目录层次结构进行组织。如果这符合您对代码的思维模型,那么就这样做吧 - 我想不出有任何害处。仅因为.NET模型未强制要求命名空间、项目和目录结构之间的关系,并不意味着如果您愿意的话,就不能有这样的关系。

我会有点担心将代码分成比所需更多的项目,因为这可能会减慢编译速度,并在管理多个程序集时增加一些开销。

编辑:请注意,这个问题几乎与应该让解决方案中的文件夹与命名空间匹配吗?相同。


抱歉,但我保证在提问之前已经进行了搜索,只是可能没有搜到正确的内容。 - Jacob Schoen

8

在.NET中,命名空间不依赖于文件系统或其他任何东西。在我看来,这是一个很大的优势。例如,您可以将代码分散到不同的程序集中,从而实现灵活的分发。

在Visual Studio中工作时,IDE会在项目树中添加新文件夹时引入新的命名空间。

这是来自MSDN的一个有用链接:

命名空间命名准则

命名命名空间的一般规则是使用公司名称,后跟技术名称,可选地包括特性和设计如下。
CompanyName.TechnologyName[.Feature][.Design]

当然,您可以按照您认为更合适的方式使用命名空间。但是,如果您要分享您的代码,我建议您遵循已接受的标准。

编辑

我强烈建议任何.NET开发人员获取框架设计准则的副本。这本书将帮助您了解.NET的设计方式和原因。


CompanyName.Technology能为你带来什么好处?我没有看到以这种方式命名事物有任何好处。有什么见解吗? - Esteban Araya
你读过MSDN的文章吗?事实上,我曾经遇到这样的情况,即两个第三方程序集使用了相同的根命名空间。 - aku
我仍然不明白那如何解决问题。如果两个第三方都叫ACME怎么办?如果他们都使用相同的技术呢? - Esteban Araya
另外,我确实阅读了这篇文章,我只是想知道您的意见。 - Esteban Araya
在我看来,这是一个概率问题。出现多个ACME的可能性最小,但FooBar随处可见。我认为微软的方案非常合理。我使用的技术来自供应商,而不是抽象的Suber.Duper.Utility类。 - aku

4

Visual Studio 解决方案通常包含一个或多个项目。这些项目有默认的命名空间(通常命名空间就是项目的名称)。通常情况下,如果你在项目中添加一个文件夹,该文件夹中的所有类都将以以下方式命名:

DefaultNamespace.FolderName.ClassName

当然,您可以更改项目的默认名称空间,并以任何您希望的方式命名您的类。
至于何时/如何将东西分解为项目,这是经验和/或偏好的问题。但是,您绝对应该在解决方案中将东西分解为项目,以保持项目的组织。如果管理太多程序集变得繁琐(如Blair所建议的),则可以始终ILMerge您的程序集成为单个程序集。ILMerge的好处在于,即使最终只有一个程序集,所有类都保留其原始的完全限定名称。
还要记住,VS解决方案与代码无关-即它们不会被构建。 VS解决方案仅是一种将项目分组的方法;它们是构建并转换为DLL的项目。
最后,VS允许您在解决方案中的任何位置添加“虚拟”文件夹。这些文件夹不映射到文件系统中的文件夹,只是用作另一种帮助您组织解决方案中的项目和其他工件的方式。

4
命名空间是一种逻辑分组方式,而项目则是一种物理分组方式。
为什么这很重要呢?想想 .NET 2.0、3.0 和 3.5。.NET 3.0 基本上就是在 .NET 2.0 的基础上添加了一些额外的程序集,而 3.5 又添加了一些程序集。例如,.NET 3.5 添加了 DataPager 控件,它是一个 Web 控件,应该被分组到 System.Web.UI.WebControls 中。如果命名空间和物理位置相同,那么由于它在不同的程序集中,就不能这样做。
因此,将命名空间作为独立的逻辑实体意味着您可以拥有几个不同程序集的成员,它们都被逻辑地分组在一起,因为它们是用来与彼此结合使用的。
(另外,物理和逻辑布局非常相似也没有问题。)

3
区别在于,.net命名空间与Java包没有太多关系。
.NET命名空间纯粹用于管理声明范围,并与文件、项目或其位置无关。
很简单,当您将“using”添加到该命名空间时,特定命名空间中声明的所有内容都是可访问的。
非常容易。
名称的选择以及使用多少个'.'分隔符完全由您决定。
VS默认向您的命名空间添加.foldernames,以尝试提供帮助。
这篇文章很好地解释了命名空间:http://www.blackwasp.co.uk/Namespaces.aspx 它还有一个示例命名约定,不过你可以自己决定命名约定;)
话虽如此,我工作过的大多数地方和与之合作的人都从公司名称开始,这是明智的,因为它使该公司的类型名称与其他库、供应商、开源项目等区分开来。

3
事实上,.Net环境允许您将代码像意大利面条一样扔到IDE/文件系统中。然而,这并不意味着这种方法是明智的。通常最好坚持项目.文件夹名称.类的方法,正如之前提到的那样。另外,将一个命名空间中的所有类都放入同一个类中也是一个非常好的主意。
在Java中,您也可以做一些奇怪的事情,并获得所有所需的"灵活性",但工具往往会强烈反对这种做法。老实说,当我被介绍进入.Net世界时,最令我困惑的事情之一就是由于相对较差的指导,这种做法可能会变得松散/不一致。不过,只要稍加思考,就可以轻松地合理组织事物。 :)

2

您可以为每个命名空间将文件夹添加到您的解决方案中。虽然它仍将编译为单个可执行文件,但它会组织您的源代码文件并产生所需的效果(我认为是这样)。

我通常为项目中的每个命名空间添加一个文件夹,并将它们按照相同的层次结构嵌套(例如MyApp.View.Dialogs)。


2

命名空间是纯粹的语义化概念。虽然它们通常反映了文件夹结构,至少在使用Visual Studio IDE时如此,但并非必须如此。

同一个命名空间可以在多个库中引用,这可能会让人感到不适,但却是事实。


1
我一直认为源文件组织和为类和对象分配标识符是两个独立的问题。我倾向于将相关的类分组,但并不是每个组都应该成为命名空间。命名空间存在(更或更少)是为了解决名称冲突的问题 - 在像 C 这样的扁平命名空间语言中,你几乎无法避免跨越自己的标识符,比如 mycompany_getcurrentdate 或 MYCGetCurrentDate,因为与第三方(或系统)库中的另一个函数发生冲突的风险更小。如果为每个逻辑分离创建一个包或命名空间,你会得到(Java 示例)类名,例如 java.lang.primitivewrapper.numeric.Integer,这基本上就是过度设计了。

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