J'ai une formation en C ++ et je comprends parfaitement et suis d'accord avec les réponses à cette question: pourquoi «utiliser namespace std;» considéré comme une mauvaise pratique?
Je suis donc étonné que, ayant une certaine expérience avec C # maintenant, je vois exactement le contraire: il
using Some.Namespace;
est littéralement utilisé partout. Chaque fois que vous commencez à utiliser un type, vous ajoutez d'abord une directive using pour son espace de noms (si ce n'est déjà fait). Je ne me souviens pas avoir vu un .cs
fichier qui n'a pas commencé using System; using System.Collections.Generic; using X.Y.Z; etc...
. En fait, si vous ajoutez un nouveau fichier via l'assistant Visual Studio, il y ajoute automatiquement des directives d'utilisation, même si vous n'en avez pas du tout besoin. Ainsi, alors que dans la communauté C ++, vous êtes essentiellement lynché, C # encourage même à le faire. C'est du moins ainsi que cela m'apparaît.
Maintenant, je comprends que l'utilisation de directives en C # et C ++ n'est pas exactement la même chose. En outre, je comprends que l'une des choses les plus méchantes que vous puissiez faire using namespace
en C ++, à savoir le placer dans un fichier d'en-tête, n'a pas d'équivalent équivalent en C # en raison de l'absence d'un concept de fichiers d'en-tête et #include
.
Cependant, malgré leurs différences, l'utilisation des directives en C # et C ++ sert le même but, qui n'a qu'à taper SomeType
tout le temps, plutôt que beaucoup plus longtemps Some.Namespace.SomeType
(en C ++ avec ::
au lieu de .
). Et dans ce même but, le danger me semble également le même: nommer les collisions.
Dans le meilleur des cas, cela entraîne une erreur de compilation, vous n'avez donc "qu'à" le corriger. Dans le pire des cas, il compile toujours et le code fait silencieusement des choses différentes de ce que vous aviez l'intention de faire. Ma question est donc la suivante: pourquoi (apparemment) utilise-t-on des directives considérées comme si inégalement mauvaises en C # et C ++?
Quelques idées de réponse que j'ai (aucune de ces réponses ne me satisfait vraiment, cependant):
Les espaces de noms ont tendance à être beaucoup plus longs et beaucoup plus imbriqués en C # qu'en C ++ (
std
vs.System.Collection.Generic
). Ainsi, il y a plus de désir et plus de gain à débruiter le code de cette façon. Mais même si cela est vrai, cet argument ne s'applique que lorsque nous regardons les espaces de noms standard. Les noms personnalisés peuvent avoir n'importe quel nom court que vous aimez, à la fois en C # et C ++.Les espaces de noms semblent être beaucoup plus "fins" en C # qu'en C ++. À titre d'exemple, en C ++ toute la bibliothèque standard est contenue dans
std
(plus quelques petits espaces de noms imbriqués commechrono
) tout en C # vousSystem.IO
,System.Threading
,System.Text
etc. Ainsi, le risque d'avoir des collisions de nommage est plus petite. Cependant, ce n'est qu'un sentiment d'intestin. Je n'ai pas vraiment compté le nombre de noms que vous "importez" avecusing namespace std
etusing System
. Et encore une fois, même si cela est vrai, cet argument ne s'applique que lorsque l'on regarde les espaces de noms standard. Les vôtres peuvent être conçus aussi fins que vous le souhaitez, en C # et en C ++.
Y a-t-il d'autres arguments? Je m'intéresse particulièrement aux faits réels (s'il y en a) et pas tellement aux opinions.
la source
Ext(this T t, long l)
qui est appelée viat.Ext(0)
. Si vous ajoutez ensuite un autre espace de noms contenant une méthode d'extensionExt(this T t, int i)
, celui-ci sera appelé à la place. Mais je ne suis pas (encore) un expert en C #.Réponses:
"using System;" n'est pas universellement considéré comme une mauvaise pratique. Voir par exemple: Pourquoi n'utilisez-vous pas la directive 'using' en C #?
Mais il peut être vrai que ce n'est pas considéré comme aussi mauvais que
using namespace std
. Probablement parce que:C # n'a pas de fichiers d'en-tête. Il est rare "d'inclure" un fichier source C # dans un autre à l'aide d'un pré-processeur.
std
l'espace de noms est presque plat, c'est-à-dire que presque toutes les fonctions, types et variables de bibliothèque standard s'y trouvent (il y a quelques exceptions comme le sous-espace de noms du système de fichiers). Il contient un nombre très, très élevé d'identifiants. À ma connaissance,System
contient beaucoup moins de noms et contient plutôt plus de sous-espaces de noms.En C #, il n'y a pas de fonctions ou variables globales. En tant que tel, le nombre d'identificateurs globaux est généralement assez petit contrairement à C ++ qui en a: En outre, il est typique d'utiliser des bibliothèques C (souvent indirectement) qui n'ont pas d'espaces de noms, et donc de placer tous leurs noms dans le global espace de noms.
Pour autant que je sache, C # n'a pas de recherche dépendante des arguments. ADL en conjonction avec le masquage de nom, la surcharge, etc. peut produire des cas où certains programmes ne sont pas affectés par un conflit de nom, tandis que d'autres sont subtilement affectés, et la capture de tous les cas de coin n'est pas possible avec les tests.
En raison de ces différences, «utiliser System;» a moins de chances de conflit de noms que
using namespace std
.De plus, "l'importation" d'espace de noms est en quelque sorte une convention qui se perpétue: s'il est conventionnel d'importer un espace de noms standard, les programmeurs essaieront généralement d'éviter de choisir des noms de cet espace de noms pour leurs propres identificateurs, ce qui contribue à réduire les problèmes avec une telle convention.
Si une telle importation est considérée comme une mauvaise pratique, les programmeurs seront même moins susceptibles de tenter d'éviter de tels conflits avec les espaces de noms importés. En tant que telles, les conventions ont tendance à se polariser pour ou contre la pratique, même si les poids des arguments entre les choix étaient à l'origine subtils.
la source
std::
). En C #, c'est beaucoup plus (System.
n'a «que» 7 caractères, mais d'autres espaces de noms imbriqués ont beaucoup plus de caractères, et les écrire partout rendrait le code complètement illisible).std::
), ne serait-ce pas un style typique d'utiliser à lausing Sys = System;
place le namespace polluant non-aliasusing
?Oui, mais vous n'avez pas exporté ce danger (lire: forcer les autres à y faire face), à cause de:
C'est donc plutôt une catégorie de choses différente.
De plus, C ++ n'est pas "conçu" pour être développé dans un IDE de la même manière que C #. C # est fondamentalement toujours écrit dans Visual Studio avec son Intellisense et ainsi de suite. Il est conçu pour être utilisé de cette façon par les personnes qui l'ont créé. Quel que soit le nombre de personnes qui utilisent un IDE pour développer en C ++, il n'est pas conçu avec ce cas d'utilisation comme une préoccupation majeure.
Oui, ça aussi.
using namespace std
etusing System.Collection.Generic
sont incomparables.Alors ne les comparez pas!
la source
using namespace std
en C ++ concerne principalement les fichiers d'en-tête. La réponse est que cela ne s'applique pas en C #.using namespace std
sont certainement pas principalement des en-têtes. Son utilisation dans les en-têtes est dangereuse. Son utilisation dans vos implémentations est déconseillée.using namespace ...
en c ++ est d'éviter la collision de noms, lausing
directive en C # introduit également la possibilité de nommer la collision, alors pourquoi ne pas l'éviter? Même si leur mise en œuvre diffère.using
déclarations C # sont par fichier qui définit un type / classe unique et que le type a normalement à voir avec un ensemble relativement étroit de concepts de domaine d'application (idéalement, principe de responsabilité unique), la probabilité de tels conflits d'espace de noms est extrêmement faible. Mais quand cela arrive est facilement réparable. Les outils de développement .NET / IDE courants vous aident beaucoup avec cela. Considérez l'ensemble de l'écosystème de développement conçu pour vous rendre plus productif en combinant le meilleur des multiples activités de développement