Mam wykształcenie C++ i w pełni rozumiem i zgadzam się z odpowiedziami na to pytanie: Dlaczego "użycie przestrzeni nazw std;" jest uważane za złą praktykę?
Jestem więc zdumiony, że mając teraz jakieś doświadczenie z C#, widzę tam dokładne przeciwieństwo:
używając Some.Namespace;``jest dosłownie używana wszędzie. Za każdym razem, gdy zaczynasz używać danego typu, dodajesz najpierw dyrektywę use dla jego przestrzeni nazw (jeśli jeszcze jej nie ma). Nie mogę sobie przypomnieć, że widziałem plik
.cs, który nie zaczynał się od
użycia System; użycie System.Collections.Generic; użycie X.Y.Z; etc...`.
W rzeczywistości, jeśli dodasz nowy plik za pomocą kreatora Visual Studio, automatycznie doda on tam pewne dyrektywy, nawet jeśli w ogóle ich nie potrzebujesz. Tak więc, podczas gdy w społeczności C++ jesteś w zasadzie zlinczowany, C# nawet zachęca do tego. Przynajmniej tak mi się to wydaje.
Teraz rozumiem, że używanie dyrektyw w C# i C++ to nie jest dokładnie to samo. Rozumiem też, że jedna z najgorszych rzeczy, jakie można zrobić z użyciem przestrzeni nazw
w C++, a mianowicie umieszczenie jej w pliku nagłówkowym, nie ma odpowiednika w C# z powodu braku koncepcji plików nagłówkowych i #include
.
Jednakże, pomimo różnic, używanie dyrektyw w C# i C+++ służy temu samemu celowi, którym jest tylko wpisywanie Niektórego typu
przez cały czas, zamiast znacznie dłuższego Niektórej.Przestrzeni nazw.SomeType
(w C+++ z ::
zamiast .
). I z tym samym celem, również niebezpieczeństwo wydaje mi się być takie samo: nazywanie kolizji.
W najlepszym przypadku skutkuje to błędem kompilacji, więc "tylko" musisz to naprawić. W najgorszym przypadku, nadal kompiluje, a kod po cichu robi inne rzeczy niż zamierzałeś. Więc moje pytanie brzmi: Dlaczego (najwyraźniej) używa się dyrektyw uważanych za tak nierównomiernie złe w C# i C++?
Kilka pomysłów na odpowiedź, które mam (żaden z nich mnie jednak tak naprawdę nie satysfakcjonuje):
Przestrzenie nazw są zwykle znacznie dłuższe i znacznie bardziej zagnieżdżone w C# niż w C+++ (std
vs. System.Collection.Generic
). Tak więc, jest więcej pożądania i więcej zysku w de-noising kodu w ten sposób. Ale nawet jeśli jest to prawda, ten argument ma zastosowanie tylko wtedy, gdy patrzymy na standardowe przestrzenie nazw. Niestandardowe mogą mieć dowolną krótką nazwę, zarówno w C# jak i C++.
Przestrzenie nazw wydają się być o wiele bardziej "drobne ziarniste" w C# niż w C+++. Jako przykład, w C++ cała standardowa biblioteka jest zawarta w std
(plus kilka małych zagnieżdżonych przestrzeni nazw jak chrono
), podczas gdy w C# masz System.IO
, System.Threading
, System.Text
itd. Tak więc, ryzyko kolizji z nazwami jest mniejsze. Jednak jest to tylko przeczucie jelitowe. Nie zliczyłem, ile nazw "importujesz" z używając przestrzeni nazw std
i używając System
. I znowu, nawet jeśli jest to prawda, ten argument ma zastosowanie tylko wtedy, gdy patrzymy na standardowe przestrzenie nazw. Twoje własne mogą być zaprojektowane tak samo drobno ziarniście jak chcesz, zarówno w C# jak i C++.
Czy jest więcej argumentów? Szczególnie interesują mnie faktyczne twarde fakty (jeśli są) i nie tyle opinie.
为什么 "使用System; "不被认为是不好的做法?
"使用System; "并不是**普遍不被认为是不好的做法。例如,请看 为什么不在C#中使用 "using "指令?
但可能确实没有被认为是 "使用命名空间std "那么糟糕*。可能是因为:
C#没有头文件。使用预处理器将一个C#源文件 "包含 "到另一个源文件中是不常见的。
std
命名空间几乎是扁平的,即几乎所有的标准库函数、类型和变量都在其中(有少数例外,如文件系统子命名空间)。它包含了非常非常多的标识符。据我了解,System
包含的名称要少得多,反而有更多的子命名空间。
在C#中,没有全局函数或变量。因此,全局标识符的数量通常相当少,而C++则有这些标识符。此外,通常使用没有命名空间的C库(通常是间接的),因此将它们的名字都放到全局命名空间中。
据我所知,C#没有依赖参数的查找功能。ADL与名称隐藏、重载等结合,会产生一些程序不受名称冲突影响的情况,而另一些程序则会受到微妙的影响,通过测试,捕捉所有的角落情况是不可行的。
由于这些差异,"使用System; "比 "使用命名空间std "发生名称冲突的几率要低。
另外,命名空间的 "导入 "在某种程度上也是一种自我延续的惯例。如果导入一个标准的命名空间是常规做法,那么程序员就会习惯性地尽量避免从该命名空间选择名称作为自己的标识符,这有助于减少这种常规做法的问题。
如果这样的导入被认为是一种不好的做法,那么程序员甚至会减少尝试这种避免与导入的命名空间冲突的做法。因此,惯例往往会变得两极分化,要么支持这种做法,要么反对这种做法,即使选择之间的论点权重原本是微妙的。
Jednak pomimo różnic, używanie dyrektyw w C# i C++ służy temu samemu celowi, którym jest konieczność wpisywania tylko SomeType przez cały czas, a nie znacznie dłuższego Some.Namespace.SomeType (w C+++ z :: zamiast .). I z tym samym celem, również niebezpieczeństwo wydaje mi się być: nazywanie kolizji.
Tak, ale nie export tego zagrożenia (czytaj: zmuszanie innych do radzenia sobie z nim), z powodu:
Teraz rozumiem, że używanie dyrektyw w C# i C++ nie jest dokładnie tym samym. Rozumiem też, że jedna z najbardziej paskudnych rzeczy, jakie można zrobić z użyciem przestrzeni nazw w C++, a mianowicie umieszczenie jej w pliku nagłówkowym, nie ma odpowiednika w C# z powodu braku koncepcji plików nagłówkowych i #include.
Jest to więc raczej inna kategoria rzeczy.
Poza tym, C++ nie jest "zaprojektowane" do rozwijania w IDE tak samo jak C#. C# jest w zasadzie zawsze pisane w Visual Studio z jego Intellisense i tym podobne. Jest zaprojektowane tak, aby mogły być używane przez ludzi, którzy je stworzyli. Bez względu na to, jak wiele osób używa IDE do tworzenia w C++, nie jest ono zaprojektowane z tym przypadkiem użycia jako przytłaczająca sprawa.
Przestrzenie nazw wydaje się być znacznie bardziej "drobnoziarniste" w C# niż w C+++.
Tak, to też. użycie przestrzeni nazw std
i użycie System.Collection.Generic
są nieporównywalne.
Więc nie porównuj ich!