Pourquoi l'utilisation de "System" n'est-elle pas considérée comme une mauvaise pratique ?

J'ai une formation en C++ et je comprends parfaitement et suis d'accord avec les réponses à cette question : Pourquoi "using namespace std ;" est-il considéré comme une mauvaise pratique ?

Je suis donc étonné que, ayant maintenant une certaine expérience du C#, je constate exactement le contraire : 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 elle n'y est pas déjà). Je ne me souviens pas avoir vu un fichier .cs qui ne commençait pas par using System ; using System.Collections.Generic ; using X.Y.Z ; etc.... En fait, si vous ajoutez un nouveau fichier via l'assistant de Visual Studio, il ajoute automatiquement des directives using, même si vous n'en avez pas besoin. Ainsi, alors que la communauté C++ vous lynche, le C# encourage même cette pratique. En tout cas, c'est ainsi qu'il me semble.

Maintenant, je comprends que l'utilisation de directives en C# et en C++ n'est pas exactement la même chose. Je comprends également que l'une des choses les plus désagréables que l'on puisse faire avec l'utilisation d'un espace de noms en C++, à savoir le mettre dans un fichier d'en-tête, n'a pas de contrepartie aussi désagréable en C# en raison de l'absence de concept de fichiers d'en-tête et de #include.

Cependant, malgré leurs différences, l'utilisation des directives en C# et en C++ sert le même objectif, qui est de n'avoir à taper que SomeType tout le temps, plutôt que le beaucoup plus long Some.Namespace.SomeType (en C++ avec :: au lieu de .). Et avec ce même objectif, le danger me semble également être le même : les collisions de nommage.

Dans le meilleur des cas, il en résulte une erreur de compilation, et il suffit de la corriger. Dans le pire des cas, la compilation se poursuit et le code fait silencieusement des choses différentes de ce que vous vouliez qu'il fasse. Ma question est donc la suivante : **Pourquoi (apparemment) l'utilisation des directives est-elle considérée comme si inégalement mauvaise en C# et en C++ ?

Quelques idées de réponse que j'ai (aucune 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). Donc, il y a plus de désir et plus de gain dans le débruitage du code de cette façon. Mais même si cela est vrai, cet argument ne s'applique que si l'on considère les espaces de noms standards. Les espaces personnalisés peuvent avoir n'importe quel nom court, aussi bien en C# qu'en C++.

  • Les espaces de noms semblent être beaucoup plus "fins" en C# qu'en C++. Par exemple, en C++, toute la bibliothèque standard est contenue dans std (plus quelques minuscules espaces de noms imbriqués comme chrono) alors qu'en C#, vous avez System.IO, System.Threading, System.Text, etc. Ainsi, le risque d'avoir des collisions de nommage est plus faible. Cependant, il ne s'agit que d'une intuition. Je n'ai pas vraiment compté le nombre de noms que vous "importez" avec "using namespace std" et "using System". Et encore une fois, même si c'est vrai, cet argument ne s'applique que lorsqu'on regarde les espaces de noms standards. Vos propres espaces de noms peuvent être conçus aussi finement que vous le souhaitez, tant en C# qu'en C++.

Y a-t-il d'autres arguments ? Je suis surtout intéressé par les faits concrets (s'il y en a) et pas tellement par les opinions.

Commentaires sur la question (31)
Solution

Pourquoi "utiliser le système" n'est-il pas considéré comme une mauvaise pratique ?

"L'utilisation du système n'est pas considérée comme une mauvaise pratique. Voir par exemple : Pourquoi n'utiliseriez-vous pas la directive "using" dans C# ?

Mais il est peut-être vrai qu'il n'est pas considéré comme aussi mauvais que "l'utilisation de l'espace de noms std". Probablement parce que :

  1. C# n'a pas de fichiers d'en-tête. Il est rare d'"inclure" un fichier source C# dans un autre en utilisant un pré-processeur.

  2. L'espace de noms `std' est presque plat, c'est-à-dire que presque toutes les fonctions, types et variables des bibliothèques standard y sont (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. A ma connaissance, le "système" contient beaucoup moins de noms, et à la place il a plus de sous-espaces de noms.

  3. En C#, il n'y a pas de fonctions ou de variables globales. En tant que tel, le nombre d'identificateurs globaux est généralement assez faible, contrairement au C++ qui en possède : De plus, 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 l'espace de noms global.

  4. Pour autant que je sache, le C# n'a pas de recherche dépendante d'un argument. La LAD, en conjonction avec le masquage de noms, la surcharge, etc. peut produire des cas où certains programmes ne sont pas affectés par un conflit de noms, tandis que d'autres le sont subtilement, et la capture de tous les cas de coin n'est pas réalisable avec les tests.

En raison de ces différences, "utiliser System ;" a moins de chance d'avoir un conflit de noms que "utiliser namespace std".


De plus, l'"importation" de l'espace de noms est en quelque sorte une convention qui se perpétue d'elle-même : S'il est conventionnel d'importer un espace de noms standard, les programmeurs essaieront par convention d'éviter de choisir des noms de cet espace de noms pour leurs propres identificateurs, ce qui contribue à réduire les problèmes liés à cette convention.

Si une telle importation est considérée comme une mauvaise pratique, les programmeurs seront alors moins enclins à tenter d'éviter les conflits avec les espaces de noms importés. Les conventions ont donc tendance à se polariser pour ou contre la pratique, même si le poids des arguments entre les choix était subtil à l'origine.


Commentaires (6)

Cependant, malgré leurs différences, l'utilisation de directives en C# et C++ sert le même objectif, qui est de ne devoir taper que SomeType tout le temps, plutôt que le bien plus long Some.Namespace.SomeType (en C++ avec : : au lieu de .). Et dans ce même but, le danger me semble également être le suivant : les collisions de noms.

Oui, mais vous n'avez pas exporté ce danger (lire : forcer les autres à y faire face), à cause de :

Maintenant, je comprends que l'utilisation de directives en C# et C++ ne sont pas exactement la même chose. Je comprends également que l'une des choses les plus désagréables que l'on puisse faire avec l'espace de noms en C++, à savoir le mettre dans un fichier d'en-tête, n'a pas d'équivalent en C# en raison de l'absence de concept de fichiers d'en-tête et de #include.

C'est donc une catégorie de chose assez différente.

De plus, le C++ n'est pas "conçu" pour être développé dans un IDE de la même manière que le C#. Le C# est en fait toujours écrit dans Visual Studio avec son Intellisense et tout le reste. Il est conçu pour être utilisé de cette manière, par les personnes qui l'ont créé. Peu importe le nombre de personnes qui utilisent un IDE pour développer en C++, il n'est pas conçu pour être utilisé de cette manière.

Les espaces de noms semblent être beaucoup plus "finement granulés" en C# qu'en C++.

Oui, c'est aussi le cas. L'utilisation des espaces de noms std et l'utilisation de System.Collection.Generic sont incomparables.

Alors ne les comparez pas !

Commentaires (5)