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

Why is "using System;" not considered bad practice?

我有 C++ 背景,我完全理解并同意这个问题的答案:Why is “using namespace std;” considered bad practice?

所以我很惊讶,现在有了一些 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++ 中使用 :: 而不是 .)。出于同样的目的,危险对我来说似乎也是一样的:命名冲突。

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

我对答案的一些想法(不过,其中 none 确实让我满意):

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

However, despite their differences, using directives in C# and C++ serve the same purpose, which is only having to type SomeType all the time, rather than the much longer Some.Namespace.SomeType (in C++ with :: instead of .). And with this same purpose, also the danger appears to be theto me: naming collisions.

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

Now, I do understand that using directives in C# and C++ are not exactly the same thing. Also, I do understand that one of the most nasty things you can do with using namespace in C++, namely putting it in a header file, has no equivalent in C# due to the lack of a concept of header files and #include.

所以这是完全不同的一类东西。

此外,C++ 不是 "designed" 以 IDE 与 C# 相同的方式开发。 C# 基本上总是用 Visual Studio 及其 Intellisense 和诸如此类的东西编写。它的设计目的是让创建它的人以这种方式使用它。无论有多少人使用 IDE 在 C++ 中进行开发,它在设计时都不会将该用例作为压倒性的关注。

Namespaces appear to be much more "fine granular" in C# than in C++.

是的,也是。 using namespace stdusing System.Collection.Generic没有可比性。

所以不要比较它们!

Why is “using System;” not considered bad practice?

"using System;" is not universally not considered a bad practice. See for example: Why would you not use the 'using' directive in C#?

But it may be true that it is not considered quite as bad as using namespace std. Probably because:

  1. C# does not have header files. It is uncommon to "include" one C# source file into another using a pre-processor.

  2. std namespace is nearly flat i.e. almost all standard library functions, types and variables are in it (there are few exceptions such as the filesystem sub-namespace). It contains very, very high number of identifiers. To my understanding, System contains much fewer names, and instead has more sub-namespaces.

  3. In C#, there are no global functions or variables. As such, the number of global identifiers is typically quite small in contrast to C++ which does have those: Furthermore, it is typical to use C libraries (often indirectly) which doesn't have namespaces, and therefore place all their names into the global namespace.

  4. As far as I know, C# has no argument dependent lookup. ADL in conjunction with name hiding, overloading etc. can produce cases where some programs are not affected by a name conflict, while others are subtly affected, and catching all corner cases is not feasible with testing.

Because of these differences, “using System;” has lower chance of name conflict than using namespace std.


Also, namespace "importing" is in a way, a self-perpetuating convention: If it is conventional to import a standard namespace, then programmers will conventionally try to avoid choosing names from that namespace for their own identifiers, which helps to reduce problems with such convention.

If such an import is considered a bad practice, then programmers will be less likely to even attempt such avoidance of conflicts with imported namespaces. As such, conventions tend to get polarised either for or against the practice, even if weights of arguments between the choices were originally subtle.