为什么"使用System;"不被认为是不好的做法?

我有C++背景,我确实完全理解并同意这个问题的答案。为什么 "使用命名空间std; "被认为是不好的做法?

所以我很惊讶,现在有了一些C#的经验,我看到那里的情况完全相反。 using Some.Namespace;简直是到处都在使用。每当你开始使用一个类型时,你首先要为其命名空间添加一个using指令(如果它不在那里的话)。我不记得见过一个".cs "文件没有以 "using System; using System.Collections.Generic; using X.Y.Z; etc... "开头。 事实上,如果你通过Visual Studio向导添加一个新文件,它会自动在那里添加一些using指令,尽管你可能根本不需要它们。因此,在C++社区,你基本上会被处死,而C#甚至鼓励这样做。至少在我看来是这样的。

现在,我明白了,在C#中使用指令和C++中使用指令并不完全是一回事。另外,我也知道,在C++中使用命名空间是最讨厌的事情之一,即把它放在头文件中,而在C#中,由于缺乏头文件和#include的概念,没有相应的讨厌的东西。

然而,尽管有区别,在C#和C++中使用指令的目的是一样的,即只需要一直输入SomeType,而不是更长的Some.Namespace.SomeType(在C++中用::代替.)。在这个相同的目的下,我认为危险也是一样的:命名冲突。

在最好的情况下,这导致了一个编译错误,所以你只需要修复它。在最坏的情况下,它仍然会被编译,而且代码会默默地做与你预期不同的事情。所以我的问题是。**为什么(显然)在C#和C++中使用指令被认为是如此不平等的坏事?

我有一些关于答案的想法(不过这些想法都不能让我真正满意)。

  • 与C++相比,C#中的命名空间往往更长,嵌套更多(stdSystem.Collection.Generic相比)。因此,这样的代码去噪的愿望更强烈,收获也更大。但是,即使这是真的,这个论点只适用于我们看标准命名空间。在C#和C++中,自定义的空间可以有任何你喜欢的短名称。

  • 命名空间在C#中似乎比在C++中更加细化。例如,在C++中,整个标准库都包含在 "std "中(加上一些微小的嵌套命名空间,如 "chrono"),而在C#中,你有 "System.IO"、"System.Threading"、"System.Text "等等。因此,出现命名冲突的风险较小。然而,这只是一种直觉。我并没有实际计算你在使用命名空间std使用System的情况下"导入"了多少名字。再说一遍,即使这是真的,这个论点也只适用于看标准命名空间的时候。在C#和C++中,你自己的命名空间可以按你的意愿设计成精细的颗粒。

还有更多的论据吗?我对实际的硬性事实特别感兴趣(如果有的话),而不是对观点感兴趣。

对该问题的评论 (31)
解决办法

为什么 "使用System; "不被认为是不好的做法?

"使用System;"并不是***普遍地不被认为是一种坏的做法。请看例子。为什么在C#中不使用'using'指令?

但它可能确实没有被认为像 "使用命名空间std "那样糟糕。可能是因为。

1.C#没有头文件。使用预处理器将一个C#源文件包含到另一个文件中是不常见的。

2.2. "std "命名空间几乎是扁平的,即几乎所有的标准库函数、类型和变量都在其中(也有少数例外,如文件系统子命名空间)。它包含非常、非常多的标识符。根据我的理解,"系统 "包含的名称要少得多,而有更多的子命名空间。

3.在C#中,没有全局函数或变量。因此,全局标识符的数量通常相当少,而C++则有这些标识符。此外,典型的情况是使用C语言库(通常是间接使用),而C语言库没有命名空间,因此将它们的名字都放在全局命名空间中。

4.据我所知,C#没有依赖参数的查找。ADL与名称隐藏、重载等结合在一起,可能会产生这样的情况:一些程序不受名称冲突的影响,而另一些程序则受到微妙的影响,而用测试来捕捉所有的角落情况是不可行的。

由于这些差异,"using System; "比 "using namespace std "出现名字冲突的几率要低。


另外,命名空间"导入"在某种程度上是一种自我延续的惯例。如果导入一个标准的名字空间是惯例,那么程序员就会按照惯例尽量避免为自己的标识符选择该名字空间的名字,这有助于减少这种惯例带来的问题。

如果这样的导入被认为是一种不好的做法,那么程序员甚至不太可能尝试这种避免与导入的名字空间冲突的做法。因此,惯例往往会变得两极化,要么支持,要么反对,即使这些选择之间的争论权重原本很微妙。

评论(6)

然而,尽管有区别,在C#和C++中使用指令的目的是一样的,即只需要一直输入SomeType,而不是更长的Some.Namespace.SomeType(在C++中用::代替.)。在这个相同的目的下,我觉得危险也是存在的:命名冲突。

是的,但是你并没有_导出那个危险(读作:强迫他人处理它),因为。

现在,我确实理解在C#中使用指令和C++中使用指令并不完全是一回事。另外,我也明白,在C++中使用命名空间可以做的最讨厌的事情之一,即把它放在头文件中,由于缺乏头文件和#include的概念,在C#中没有对应的东西。

因此,这是一个相当不同的类别的事情。

另外,C++不是像C#那样被设计成可以在IDE中开发的。C#基本上都是在Visual Studio中编写的,它有Intellisense和其他东西。它被设计成这样,由创造它的人使用。不管有多少人使用IDE来开发C++,它的设计都不是以这种使用情况为主导的。

命名空间在C#中似乎比在C++中更加细化。

是的,这也是。使用命名空间std使用System.Collection.Generic是不可比拟的。

所以不要比较它们

评论(5)