首页 > 解决方案 > 为什么是“使用系统”;不被认为是不好的做法?

问题描述

我有 C++ 背景,我完全理解并同意这个问题的答案:Why is “using namespace 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++ 中可以做的最using namespace讨厌的事情之一,即把它放在头文件中,由于缺少头文件和#include.

然而,尽管存在差异,但在 C# 和 C++ 中使用指令具有相同的目的,即只需要一直键入SomeType,而不是更长的时间Some.Namespace.SomeType(在 C++ 中使用::而不是.)。出于同样的目的,对我来说危险似乎也是一样的:命名冲突。

在最好的情况下,这会导致编译错误,因此您“只需”修复它。在最坏的情况下,它仍然可以编译,并且代码会默默地执行与您预期不同的事情。所以我的问题是:为什么(显然)使用在 C# 和 C++ 中被认为非常糟糕的指令?

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

还有更多的争论吗?我对实际确凿的事实(如果有的话)特别感兴趣,而不是对意见感兴趣。

标签: c#c++using-directives

解决方案


为什么是“使用系统;” 不被认为是不好的做法?

“使用系统;” 并非普遍认为是不好的做法例如,请参阅:为什么不在 C# 中使用“使用”指令?

但它可能没有被认为是那么糟糕using namespace std。可能是因为:

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

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

  3. 在 C# 中,没有全局函数或变量。因此,与确实有这些的 C++ 相比,全局标识符的数量通常非常少:此外,通常使用没有命名空间的 C 库(通常是间接的),因此将它们的所有名称放入全局命名空间。

  4. 据我所知,C# 没有依赖于参数的查找。ADL 与名称隐藏、重载等相结合可能会产生一些程序不受名称冲突影响的情况,而另一些则受到轻微影响,并且通过测试捕获所有极端情况是不可行的。

由于这些差异,“使用系统;” 名称冲突的可能性低于using namespace std.


此外,命名空间“导入”在某种程度上是一种自我延续的约定:如果按照惯例导入标准命名空间,那么程序员通常会尝试避免从该命名空间中选择名称作为自己的标识符,这有助于减少与这样的约定。

如果这种导入被认为是一种不好的做法,那么程序员甚至不太可能尝试避免与导入的命名空间发生冲突。因此,即使选择之间的争论的权重最初是微妙的,惯例也会倾向于支持或反对这种做法。


推荐阅读