8

我的背景主要是作为一名 Java 开发人员,但最近我一直在做一些 .NET 方面的工作。所以我一直在尝试在家里做一些简单的项目来更好地使用.NET。我已经能够将我的大部分 Java 经验转移到使用 .NET(特别是 C#)中,但唯一真正让我困惑的是命名空间。

我知道命名空间类似于 Java 包,但据我所知,主要区别在于 Java 包使用实际的文件夹来显示分隔,而在 .NET 中则没有,所有文件都位于一个文件夹中并且命名空间只是在每个类中声明。

我觉得这很奇怪,因为我总是将包视为组织和分组相关代码的一种方式,使其更易于导航和理解。由于在 .NET 中它不能以这种方式工作,加班后,该项目显得更加拥挤并且不那么容易导航。

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

编辑:正如布莱尔指出的,这与这里提出的问题几乎相同。

4

9 回答 9

11

我不能声称这是最佳实践,但我经常看到文件组织在一个目录层次结构中,该目录层次结构反映了命名空间。如果它更适合您的代码心智模型,那么就这样做 - 我想不出有什么害处。仅仅因为 .NET 模型不强制命名空间、项目和目录结构之间的关系并不意味着如果你愿意,你就不能拥有这样的关系。

对于将代码分解成比您需要的更多的项目,我会有点谨慎,因为当您必须管理多个程序集时,这会减慢编译速度并增加一点开销。

编辑:请注意,这个问题几乎与解决方案中的文件夹是否应与命名空间匹配?

于 2008-09-11T02:29:49.687 回答
8

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

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

这是来自 MSDN 的有用链接:

命名空间命名准则

命名命名空间的一般规则是使用公司名称,后跟技术名称以及可选的功能和设计,如下所示。
CompanyName.TechnologyName[.Feature][.Design]

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

编辑

我强烈建议任何 .net 开发人员获取一份《框架设计指南》,这本书将帮助您了解.NET 的设计方式原因。

于 2008-09-11T02:31:12.400 回答
4

一个 VS 解决方案通常包含一个或多个项目。这些项目具有默认命名空间(通常命名空间就是项目的名称)。通常,如果您在项目中添加一个文件夹,则其中的所有类将命名如下:

DefaultNamespace.FolderName.ClassName

当然,您可以更改项目的默认命名空间,并以您希望的任何方式命名您的类。

至于何时/如何将内容分解为项目,这是经验和/或偏好的问题。但是,您绝对应该在解决方案中将内容分解为项目,以使您的项目井井有条。如果管理太多程序集变得很麻烦(正如 Blair 建议的那样),您始终可以您的程序集合并到一个程序集中。ILMerge 的优点在于,即使您最终只得到一个程序集,您的所有类都保留其原始的完全限定名称。

同样重要的是要记住 VS 解决方案与代码无关 - 即。他们没有被建造。VS Solutions 只不过是一种对项目进行分组的方式;它是构建并转换为 DLL 的项目。

最后,VS 让您可以在解决方案的任何位置添加“虚拟”文件夹。这些文件夹不映射到文件系统中的文件夹,只是用作帮助您在解决方案中组织项目和其他工件的另一种方式。

于 2008-09-11T02:31:07.563 回答
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. 如果名称空间和物理位置相同,则不可能是因为它位于不同的程序集中。

因此,将命名空间作为独立的逻辑实体意味着您可以拥有多个不同程序集的成员,这些程序集都在逻辑上组合在一起,因为它们旨在相互结合使用。

(另外,让你的物理和逻辑布局非常相似并没有错。)

于 2008-09-12T03:30:14.043 回答
3

事实上,.Net 环境允许您将代码扔到 IDE/文件系统,就像意大利面条靠墙一样。

然而,这并不意味着这种方法是理智的。坚持前面提到的 project.foldername.Class 方法通常是个好主意。将一个命名空间中的所有类保存到同一个类中也是一个非常好的主意。

在 Java 中,您可以做类似这样的麻烦事来获得您想要的所有“灵活性”,但这些工具往往会强烈反对它。老实说,对我来说,在被介绍给 .Net 世界时最令人困惑的事情之一就是由于相对较差的指导,这可能是多么草率/不一致。不过,只要稍加思考,就很容易将事情整理得井井有条。:)

于 2008-09-11T02:37:01.417 回答
3

不同之处在于 .net 命名空间与 java 包没有多大关系。

.net 命名空间纯粹用于管理声明范围,与文件、项目或其位置无关。

当您在该命名空间中包含“使用”时,可以访问在特定命名空间中声明的所有内容。

好简单。

名称的选择以及是否/有多少“。” 您使用的分隔符完全取决于您。

VS 默认添加 .foldernames 到你的命名空间只是为了尝试和提供帮助。

这篇文章很好地解释了命名空间:http: //www.blackwasp.co.uk/Namespaces.aspx

它最后还有一个示例命名约定,尽管您的命名约定是您的电话!;)

也就是说,我工作过的大多数地方和与我共事过的人都以公司名称开头,这是明智的,因为它使该公司的类型名称与众不同,(与其他库、供应商、开源项目等分开)

于 2009-12-04T14:24:01.627 回答
2

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

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

于 2008-09-11T02:30:49.607 回答
2

命名空间是纯语义的。虽然它们通常确实反映了文件夹结构,但至少在使用 Visual Studio IDE 时,它们不需要这样做。

您可以在多个库中引用相同的命名空间,虽然丑陋但真实。

于 2008-09-11T02:31:13.897 回答
1

我一直认为源文件组织和为类和对象分配标识符是两个独立的问题。我倾向于将相关的类保存在组中,但并不是每个组都应该是一个命名空间。命名空间的存在(或多或少)是为了解决名称冲突的问题——在像 C 这样的平面命名空间语言中,你不能走两英尺而不绊倒像mycompany_getcurrentdateor之类的标识符MYCGetCurrentDate,因为与第三个函数中的另一个函数发生冲突的风险——派对(或系统)库要小得多。如果您为每个逻辑分隔都创建了一个包或命名空间,您会得到(Java 示例)类名,例如java.lang.primitivewrapper.numeric.Integer,这几乎是多余的。

于 2008-09-11T02:38:17.920 回答