提问人:sebrockm 提问时间:2/4/2020 最后编辑:sebrockm 更新时间:2/5/2020 访问量:5500
为什么“使用系统”不被认为是不好的做法?
Why is "using System;" not considered bad practice?
问:
我有C++背景,我完全理解并同意这个问题的答案:为什么“使用命名空间std;”被认为是不好的做法?
因此,令我惊讶的是,现在有了 C# 的一些经验,我看到的情况恰恰相反:实际上无处不在。每当开始使用某个类型时,首先为其命名空间添加一个 using 指令(如果该指令尚不存在)。我不记得见过一个不以 .
事实上,如果通过 Visual Studio 向导添加新文件,它会自动在此处添加一些 using 指令,即使你可能根本不需要它们。因此,虽然在C++社区中,你基本上会被私刑处死,但C#甚至鼓励这样做。至少在我看来是这样。using Some.Namespace;
.cs
using System; using System.Collections.Generic; using X.Y.Z; etc...
现在,我确实明白在 C# 和 C++ 中使用指令并不完全是一回事。另外,我确实知道,您可以在 C++ 中做的最讨厌的事情之一,即将其放在头文件中,由于缺乏头文件的概念,因此在 C# 中没有同样令人讨厌的对应项。using namespace
#include
但是,尽管存在差异,但在 C# 和 C++ 中使用指令具有相同的目的,即只需要一直键入,而不是更长的(在 C++ 中 with 而不是 )。出于同样的目的,对我来说,危险似乎也是一样的:命名碰撞。SomeType
Some.Namespace.SomeType
::
.
在最好的情况下,这会导致编译错误,因此您“只需要”修复它。在最坏的情况下,它仍然会编译,并且代码会静默地执行与您预期不同的操作。所以我的问题是:为什么(显然)在 C# 和 C++ 中使用指令被认为是如此不公平的?
我有一些关于答案的想法(不过,这些都没有真正让我满意):
命名空间在 C# 中往往比在 C++ 中更长,嵌套也更多( vs. )。因此,以这种方式对代码进行去噪会有更多的愿望和更多的收益。但即使这是真的,这个论点也只适用于我们查看标准命名空间的情况。自定义名称可以在 C# 和 C++ 中具有您喜欢的任何短名称。
std
System.Collection.Generic
命名空间在 C# 中似乎比在 C++ 中更“细粒度”。例如,在 C++ 中,整个标准库包含在(加上一些微小的嵌套命名空间,如 )中,而在 C# 中,您有 、 等。因此,发生命名冲突的风险较小。然而,这只是一种直觉。我实际上没有计算过你“导入”了多少个名字和 .同样,即使这是真的,这个论点也只适用于查看标准命名空间。您自己的可以根据需要在 C# 和 C++ 中设计为精细粒度。
std
chrono
System.IO
System.Threading
System.Text
using namespace std
using System
还有更多的争论吗?我对实际的确凿事实(如果有的话)特别感兴趣,而不是对意见感兴趣。
答:
但是,尽管存在差异,但在 C# 和 C++ 中使用指令具有相同的目的,即只需始终键入 SomeType,而不是更长的 Some.Namespace.SomeType(在 C++ 中使用 :: 而不是 .)。出于同样的目的,对我来说,危险似乎也存在:命名碰撞。
是的,但你没有输出这种危险(阅读:强迫其他人处理它),因为:
现在,我确实明白在 C# 和 C++ 中使用指令并不完全是一回事。此外,我确实知道,在 C++ 中使用命名空间可以做的最令人讨厌的事情之一,即将其放在头文件中,由于缺乏头文件和 #include 的概念,在 C# 中没有等效项。
所以这是一个不同的类别。
此外,C++ 的“设计”不是像 C# 那样在 IDE 中开发的。C# 基本上总是用 Visual Studio 编写的,带有 Intellisense 等。它被设计为由创建它的人以这种方式使用。无论有多少人使用 IDE 在 C++ 中进行开发,它的设计都不是将该用例作为压倒性的关注点。
命名空间在 C# 中似乎比在 C++ 中更“细粒度”。
是的,那也是。 并且是无可比拟的。using namespace std
using System.Collection.Generic
所以不要比较它们!
评论
using namespace std
using namespace std
using namespace ...
using
using
为什么“使用系统”不被认为是不好的做法?
“使用系统”并不是普遍不被认为是一种不好的做法。例如,请参阅:为什么在 C# 中不使用“using”指令?
但它可能确实被认为没有 .可能是因为:using namespace std
C# 没有头文件。使用预处理器将一个 C# 源文件“包含”到另一个 C# 源文件中的情况并不常见。
std
命名空间几乎是扁平的,即几乎所有的标准库函数、类型和变量都在其中(很少有例外,例如文件系统子命名空间)。它包含非常非常多的标识符。据我了解,包含的名称要少得多,而是具有更多的子命名空间。System
在 C# 中,没有全局函数或变量。因此,与具有全局标识符的C++相比,全局标识符的数量通常非常少: 此外,通常使用没有命名空间的 C 库(通常是间接的),因此将它们的所有名称都放在全局命名空间中。
据我所知,C#没有与参数相关的查找。ADL 与名称隐藏、重载等相结合,可能会产生一些程序不受名称冲突影响的情况,而其他程序则受到微妙的影响,并且通过测试捕获所有极端情况是不可行的。
由于这些差异,“using System;”出现名称冲突的几率低于 。using namespace std
此外,命名空间“导入”在某种程度上是一种自我延续的约定:如果导入标准命名空间是约定俗成的,那么程序员通常会尽量避免从该命名空间中选择名称作为他们自己的标识符,这有助于减少这种约定的问题。
如果这样的导入被认为是一种不好的做法,那么程序员甚至不太可能尝试避免与导入的命名空间发生冲突。因此,惯例往往会变得两极分化,要么支持或反对这种做法,即使选择之间的争论权重最初是微妙的。
评论
std::
System.
std::
using Sys = System;
using
下一个:为什么使用声明不能解决钻石问题?
评论
Ext(this T t, long l)
t.Ext(0)
Ext(this T t, int i)