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

seb*_*ckm 54 c# c++ using-directives

我有 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++ 中使用指令并不完全相同。另外,我确实明白,您可以using namespace在 C++ 中做的最讨厌的事情之一,即将它放在头文件中,由于缺乏头文件和#include.

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

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

我对答案的一些想法(不过,这些都没有真正让我满意):

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

  • 命名空间在 C# 中似乎比在 C++ 中更“细粒度”。举个例子,在C ++整个标准库包含在std(加上一些微小的嵌套的命名空间一样chrono),而在C#中你有System.IOSystem.ThreadingSystem.Text等,所以,其命名冲突的风险较小。然而,这只是一种直觉。我实际上并没有计算你用using namespace std和 来“导入”了多少个名字using System。再说一次,即使这是真的,这个论点也只适用于查看标准命名空间。您可以按照自己的意愿在 C# 和 C++ 中将自己的内容设计为细粒度的。

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

eer*_*ika 34

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

“使用系统;” 是不是普遍不被认为是不好的做法。参见示例:为什么不在 C# 中使用“using”指令?

但它可能是真实的,它不被认为很糟糕using namespace std。大概是因为:

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

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

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

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

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


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

如果这样的导入被认为是不好的做法,那么程序员甚至不太可能尝试避免与导入的命名空间发生冲突。因此,即使选择之间的争论权重最初是微妙的,惯例往往会变得两极分化,无论是支持还是反对实践。

  • 这仅考虑开放命名空间的潜在缺点。这是一个开始,但我认为我们还需要考虑优点:就 C++ 而言,大多数情况下它可以节省五个字符(`std::`)。在 C# 中,它的数量要多得多(“System.”“只有”7 个字符,但其他嵌套命名空间有“很多”更多的字符,将它们写在任何地方都会使代码完全不可读)。 (4认同)
  • @KonradRudolph 如果认为缺点很重要,并且输入量同样如此(与输入 `std::` 的量相比),那么使用 `using Sys = System;` 代替污染非命名空间的方式不是典型的风格吗?别名“使用”? (4认同)
  • @Bathsheba关于“权威”,我想声明我对C#知之甚少,我的答案是基于C++的知识,以及一些关于C#的谷歌搜索。所以,如果有人检查一下 C# 部分,我将不胜感激:) (2认同)
  • 关于ADL部分:C#有扩展方法。它的设计与 ADL 不同,但它们在命名冲突方面存在相同的问题。 (2认同)