Ich habe einen C ++ - Hintergrund und verstehe die Antworten auf diese Frage voll und ganz und stimme ihnen zu: Warum wird der Namespace std verwendet? als schlechte Praxis angesehen?
Ich bin erstaunt, dass ich nach einigen Erfahrungen mit C # genau das Gegenteil sehe:
using Some.Namespace;
Wird buchstäblich überall verwendet. Wenn Sie einen Typ verwenden, fügen Sie zuerst eine using-Direktive für seinen Namespace hinzu (falls diese noch nicht vorhanden ist). Ich kann mich nicht erinnern, eine .cs
Datei gesehen zu haben, die nicht damit begonnen hat using System; using System.Collections.Generic; using X.Y.Z; etc...
. Wenn Sie eine neue Datei über den Visual Studio-Assistenten hinzufügen, werden dort automatisch einige mithilfe von Anweisungen hinzugefügt, auch wenn Sie diese möglicherweise überhaupt nicht benötigen. Während Sie in der C ++ - Community im Grunde genommen gelyncht werden, empfiehlt C # dies sogar. Zumindest erscheint es mir so.
Jetzt verstehe ich, dass die Verwendung von Direktiven in C # und C ++ nicht genau dasselbe ist. Ich verstehe auch, dass eines der schlimmsten Dinge, mit denen Sie using namespace
in C ++ arbeiten können, nämlich das Einfügen in eine Header-Datei, aufgrund des Fehlens eines Konzepts für Header-Dateien und in C # kein gleichwertiges Gegenstück hat #include
.
Trotz ihrer Unterschiede dient die Verwendung von Direktiven in C # und C ++ demselben Zweck, der nur die SomeType
ganze Zeit eingegeben werden muss und nicht der viel längere Some.Namespace.SomeType
(in C ++ mit ::
statt .
). Und mit dem gleichen Zweck scheint mir auch die Gefahr dieselbe zu sein: Kollisionen zu benennen.
Im besten Fall führt dies zu einem Kompilierungsfehler, sodass Sie ihn "nur" beheben müssen. Im schlimmsten Fall wird es immer noch kompiliert und der Code macht stillschweigend andere Dinge, als Sie beabsichtigt hatten. Meine Frage lautet also: Warum werden (anscheinend) Direktiven verwendet, die in C # und C ++ als so ungleich schlecht angesehen werden?
Einige Ideen für eine Antwort, die ich habe (keine davon befriedigt mich jedoch wirklich):
Namespaces sind in C # in der Regel viel länger und viel stärker verschachtelt als in C ++ (
std
vs.System.Collection.Generic
). Es gibt also mehr Lust und mehr Gewinn, den Code auf diese Weise zu entrauschen. Aber selbst wenn dies zutrifft, gilt dieses Argument nur, wenn wir uns die Standard-Namespaces ansehen. Benutzerdefinierte können in C # und C ++ einen beliebigen Kurznamen haben.Namespaces scheinen in C # viel "feinkörniger" zu sein als in C ++. Als Beispiel ist in C ++ die gesamte Standardbibliothek enthalten in
std
(plus einige kleine verschachtelte Namensräume wiechrono
) , während in C # Sie habenSystem.IO
,System.Threading
,System.Text
etc. So wird das Risiko von Namenskollisionen mit kleiner. Dies ist jedoch nur ein Bauchgefühl. Ich habe nicht gezählt, wie viele Namen Sie mitusing namespace std
und "importieren"using System
. Auch wenn dies zutrifft, gilt dieses Argument nur für die Standard-Namespaces. Ihre eigenen können sowohl in C # als auch in C ++ so feinkörnig gestaltet werden, wie Sie möchten.
Gibt es mehr Argumente? Ich interessiere mich besonders für aktuelle harte Fakten (falls vorhanden) und nicht so sehr für Meinungen.
quelle
Ext(this T t, long l)
, die via aufgerufen wirdt.Ext(0)
. Wenn Sie dann einen anderen Namespace hinzufügen, der eine Erweiterungsmethode enthältExt(this T t, int i)
, wird dieser stattdessen aufgerufen. Aber ich bin (noch) kein Experte für C #.Antworten:
"using System;" wird nicht allgemein als schlechte Praxis angesehen. Siehe zum Beispiel: Warum würden Sie die 'using'-Direktive nicht in C # verwenden?
Aber es kann wahr sein, dass es nicht ganz so schlimm ist wie
using namespace std
. Vielleicht weil:C # hat keine Header-Dateien. Es ist ungewöhnlich, eine C # -Quelldatei mit einem Vorprozessor in eine andere "einzuschließen".
std
Der Namespace ist nahezu flach, dh fast alle Standardbibliotheksfunktionen, -typen und -variablen sind darin enthalten (es gibt nur wenige Ausnahmen wie den Subsystem-Namespace des Dateisystems). Es enthält sehr, sehr viele Bezeichner.System
Enthält nach meinem Verständnis viel weniger Namen und stattdessen mehr Sub-Namespaces.In C # gibt es keine globalen Funktionen oder Variablen. Daher ist die Anzahl der globalen Bezeichner im Gegensatz zu C ++, das diese hat, normalerweise recht gering: Darüber hinaus ist es typisch, C-Bibliotheken (häufig indirekt) zu verwenden, die keine Namespaces haben, und daher alle ihre Namen in die globalen zu setzen Namespace.
Soweit ich weiß, hat C # keine argumentabhängige Suche. ADL in Verbindung mit dem Ausblenden, Überladen usw. von Namen kann zu Fällen führen, in denen einige Programme nicht von einem Namenskonflikt betroffen sind, während andere subtil betroffen sind und das Abfangen aller Eckfälle beim Testen nicht möglich ist.
Aufgrund dieser Unterschiede wird "using System" verwendet. hat eine geringere Wahrscheinlichkeit für Namenskonflikte als
using namespace std
.Das "Importieren" von Namespaces ist in gewisser Weise eine sich selbst aufrechterhaltende Konvention: Wenn es üblich ist, einen Standard-Namespace zu importieren, versuchen Programmierer herkömmlicherweise , die Auswahl von Namen aus diesem Namespace für ihre eigenen Bezeichner zu vermeiden, um Probleme mit zu reduzieren solche Konvention.
Wenn ein solcher Import als schlechte Praxis angesehen wird, ist es weniger wahrscheinlich, dass Programmierer versuchen, Konflikte mit importierten Namespaces zu vermeiden. Konventionen tendieren daher dazu, entweder für oder gegen die Praxis zu polarisieren, selbst wenn die Gewichtung der Argumente zwischen den Entscheidungen ursprünglich subtil war.
quelle
std::
). In C # ist es wesentlich mehr (System.
hat "nur" 7 Zeichen, aber andere verschachtelte Namespaces haben viel mehr Zeichen, und wenn Sie sie überall ausschreiben, wird der Code vollständig unlesbar).std::
), wäre es nicht ein typischer Stil,using Sys = System;
stattdessen den Namespace zu verwenden, der Nicht-Alias verschmutztusing
?Ja, aber Sie haben diese Gefahr nicht exportiert (lesen Sie: andere dazu zwingen, damit umzugehen), weil:
Es ist also eher eine andere Kategorie von Dingen.
Außerdem ist C ++ nicht so konzipiert, dass es in einer IDE wie C # entwickelt wird. C # wird grundsätzlich immer in Visual Studio mit Intellisense und so weiter geschrieben. Es wurde entwickelt, um von den Menschen, die es erstellt haben, auf diese Weise verwendet zu werden. Unabhängig davon, wie viele Benutzer eine IDE für die Entwicklung in C ++ verwenden, ist sie nicht mit diesem Anwendungsfall als überwältigendes Problem konzipiert.
Ja das auch.
using namespace std
undusing System.Collection.Generic
sind unvergleichlich.Also vergleiche sie nicht!
quelle
using namespace std
in C ++ zu vermeidende Rat bezieht sich hauptsächlich auf Header-Dateien. Die Antwort ist, dass dies in C # nicht gilt.using namespace std
geht es sicherlich nicht hauptsächlich um Header. Die Verwendung in Headern ist gefährlich. Von der Verwendung in Ihren Implementierungen wird abgeraten.using namespace ...
in c ++ vermeiden sollten, besteht darin, Namenskollisionen zu vermeiden. Dieusing
Anweisung in C # führt auch die Möglichkeit ein, Kollisionen zu benennen. Warum sollten Sie sie dann nicht vermeiden? Auch wenn dort die Umsetzung unterschiedlich ist.using
-Deklarationen pro Datei vorliegen, die einen einzelnen Typ / eine einzelne Klasse definiert, und der Typ normalerweise mit einem relativ engen Satz von Anwendungsdomänenkonzepten (im Idealfall dem Prinzip der einzelnen Verantwortung) zu tun hat, ist die Wahrscheinlichkeit solcher Namespace-Konflikte äußerst gering. Aber wenn passieren, sind leicht zu beheben. Gängige .NET-Entwicklungstools / IDE helfen Ihnen dabei sehr. Betrachten Sie das gesamte Entwicklungsökosystem, das Sie produktiver machen soll, indem Sie das Beste aus mehreren Entwicklungsaktivitäten kombinieren