【发布时间】:2020-05-19 10:08:42
【问题描述】:
我有 C++ 背景,我完全理解并同意这个问题的答案:Why is “using namespace std;” considered bad practice?
所以我很惊讶,现在有了一些 C# 经验,我看到了完全相反的情况:
using Some.Namespace; 字面上到处都在使用。每当你开始使用一个类型时,你首先为它的命名空间添加一个 using 指令(如果它还没有的话)。我不记得曾经看过不是以using System; using System.Collections.Generic; using X.Y.Z; etc... 开头的.cs 文件。
事实上,如果您通过 Visual Studio 向导添加一个新文件,它会自动在其中添加一些 using 指令,即使您可能根本不需要它们。因此,虽然在 C++ 社区中你基本上会被处以私刑,但 C# 甚至鼓励这样做。至少在我看来是这样的。
现在,我明白在 C# 和 C++ 中使用指令并不完全相同。另外,我确实理解在 C++ 中使用 using namespace 可以做的最讨厌的事情之一,即把它放在头文件中,由于缺少头文件和 #include 的概念,在 C# 中没有同等讨厌的对应物.
但是,尽管存在差异,但在 C# 和 C++ 中使用指令的目的相同,即只需一直键入 SomeType,而不是更长的 Some.Namespace.SomeType(在 C++ 中使用 :: 而不是.)。出于同样的目的,对我来说危险似乎也是一样的:命名冲突。
在最好的情况下,这会导致编译错误,因此您“只需”修复它。在最坏的情况下,它仍然可以编译,并且代码会默默地执行与您预期不同的事情。所以我的问题是:为什么(显然)使用在 C# 和 C++ 中被认为非常糟糕的指令?
我对答案的一些想法(不过,这些想法都不能让我真正满意):
命名空间在 C# 中往往比在 C++ 中更长且嵌套更多(
std与System.Collection.Generic)。因此,以这种方式对代码进行去噪有更多的愿望和更多的收获。但即使这是真的,这个论点也只适用于我们查看标准命名空间时。在 C# 和 C++ 中,自定义名称可以使用任何您喜欢的短名称。命名空间在 C# 中似乎比在 C++ 中更“细粒度”。例如,在 C++ 中,整个标准库包含在
std中(加上一些小的嵌套命名空间,如chrono),而在 C# 中,您有System.IO、System.Threading、System.Text等。所以,风险命名冲突较小。然而,这只是一种直觉。我实际上并没有计算你用using namespace std和using System“导入”了多少个名字。同样,即使这是真的,这个论点也只适用于标准命名空间。您可以根据自己的意愿在 C# 和 C++ 中将您自己的设计设计为细粒度。
还有更多的论据吗?我对真实的事实(如果有的话)特别感兴趣,而不是意见。
【问题讨论】:
-
@Timo OP 明确不询问标头污染问题。
-
我认为这是因为全局命名空间没有与 C++ 相同程度的竞争(主要是由于 C 标准库)。但我等待最了解的人的答案。
-
@ThomasWeller 在 C++ 中很明显。在 C# 中,考虑通过
t.Ext(0)调用的带有Ext(this T t, long l)的扩展方法。如果您随后添加另一个包含扩展方法Ext(this T t, int i)的命名空间,则会调用该命名空间。但我还不是 C# 方面的专家。 -
@Franck 即使我同意你这一点,那么同样的论点也适用于 C++,进一步推动了我看不到 C++ 和 C# 之间区别的问题
-
@Franck C++ 会在出现歧义时向您抛出编译器错误。以及 C#。
标签: c# c++ using-directives