Utilisations globales en C# 10 et .NET 6 en 10 minutes ou moins
[[academy-video-youtube({"vid": "RWYrafpP53A", "start_time": "0", "title": "Global Usings in C# 10 and .NET 6 In 10 Minutes or Less", "creator": "Tim Corey", "length": "5m 33s"})]]
Quiconque a parcouru le début d'un fichier C# connaît la cérémonie : une colonne de déclarations using empilée au-dessus de chaque déclaration de classe, se répétant d'un fichier à l'autre. Un projet typique intègre les mêmes quelques namespaces encore et encore, et les modifier tous quand on doit changer est une corvée qui n'apporte aucun avantage réel. C# 10 a ajouté la directive using global pour supprimer cette répétition dans tout le projet.
Dans sa vidéo "Global Usings in C# 10 and .NET 6 In 10 Minutes or Less", Tim Corey explique ce que les usings globaux font, où les placer pour que l'équipe puisse les trouver, et la variante statique qui vous permet de supprimer un préfixe de classe des appels de membres. Il souligne également le piège de conception à garder à l'esprit : importer un namespace globalement expose tout le projet à tout nom à l'intérieur. Quiconque a copié les mêmes cinq lignes using dans chaque nouvelle classe trouvera ici le modèle de nettoyage.
Le problème de la répétition
[0:17 - 1:50] Tim commence avec une nouvelle application console .NET 6 et crée un dossier Data contenant une classe PersonModel. Référencer cette classe depuis Program.cs nécessite la ligne attendue using GlobalUsings.Data; en haut du fichier. Ajouter une seconde classe qui a également besoin de PersonModel signifie ajouter la même ligne using en haut de ce fichier aussi. Avec une demi-douzaine de classes, le même import s'écrit une demi-douzaine de fois.
C'est exactement la situation pour laquelle global using a été conçu. Tout namespace, type ou classe statique dont dépend l'ensemble du projet peut être déclaré une fois et rendu disponible pour chaque fichier sans répétition par fichier.
Promotion d'un using à portée globale
[1:50 - 2:24] La syntaxe est un seul mot-clé devant la directive existante :
global using GlobalUsings.Data;
global using GlobalUsings.Data;
Cette seule ligne, placée dans n'importe quel fichier .cs du projet, rend GlobalUsings.Data disponible dans tous les autres fichiers du même projet. Les autres classes qui avaient auparavant besoin de leur propre ligne using pour PersonModel n'en ont plus besoin; le type se résout automatiquement. La portée s'arrête à la limite du projet, donc référencer des classes d'un projet frère nécessite toujours la référence de projet normale plus son propre using global ou par fichier.
Ce que cela ne fait pas, c'est cacher d'où viennent les types. Le compilateur résout toujours PersonModel vers son espace de noms; le namespace est simplement pré-importé. Le comportement à l'exécution est identique à l'écriture du même using en haut de chaque fichier.
Centralisation des usings dans un fichier
[2:24 - 3:32] Parsemer des directives using globales dans des fichiers au hasard est techniquement valide mais opérationnellement désordonné. Si un nouveau membre de l'équipe voit PersonModel se résoudre sans importation apparente, il doit utiliser grep pour trouver où il a été rendu global dans le projet. La convention évolutive est de garder tous les usings globaux dans un seul fichier à la racine du projet, nommé quelque chose de prévisible comme Usings.cs ou GlobalUsings.cs :
// Usings.cs at the project root
global using GlobalUsings.Data;
global using System.Text.Json;
global using System.Collections.Concurrent;
// Usings.cs at the project root
global using GlobalUsings.Data;
global using System.Text.Json;
global using System.Collections.Concurrent;
Le fichier ne contient rien d'autre. Quiconque rejoint le projet sait exactement où chercher pour voir ce qui est disponible globalement. Cela s'aligne avec les namespaces basés sur les fichiers et autres fonctionnalités qui réduisent la cérémonie apparues dans les récentes versions de C#, toutes visant à rendre le cadre du projet facile à lire d'un seul coup d'œil.
Using global statique pour l'importation de méthodes
[3:32 - 4:50] La directive using global se compose avec la forme using statique ajoutée plus tôt. La combinaison vous permet de supprimer le préfixe de la classe d'un membre de classe statique dans tout le projet. Le cas motivant que Tim montre est Console.WriteLine :
global using static System.Console;
global using static System.Console;
Avec cette seule ligne dans le fichier usings centralisé, Console.WriteLine("hello") devient simplement WriteLine("hello") partout dans le projet. Le même modèle fonctionne pour les aides mathématiques (global using static System.Math vous permet d'écrire Sqrt(x) sans le préfixe) et pour toute autre classe statique sur laquelle repose fortement votre code.
C'est la forme dont Tim est le plus prudent. Supprimer le préfixe de la classe est un gain de lisibilité lorsque les méthodes sont évidentes, mais cela peut devenir une source de confusion lorsqu'il existe deux classes statiques exposant des méthodes portant le même nom. Un lecteur regardant un appel WriteLine nu doit faire confiance au fichier central plutôt que de voir la source dans le contexte.
Quand les importations globales se superposent
[4:50 - 5:14] Le but entier des namespaces est de garder les types ayant le même nom court de se heurter. Importer globalement un namespace enlève ce tampon pour tout le projet en une fois. Si votre espace de noms GlobalUsings.Data contient une classe Data et que vous importez également de manière globale System.Data, chaque fichier doit maintenant désambiguïser. Le coût apparaît non pas là où le conflit se produit mais dans tout fichier futur pris entre les deux.
Les conseils de Tim consistent à utiliser les usings globaux avec précaution, préférer les namespaces dont vous savez que le projet dépend universellement, et rester particulièrement prudent avec l'utilisation globale statique. Un ensemble de départ raisonnable est les namespaces que chaque fichier importe de toute façon ; dépassez cette liste appelle une révision de code.
Conclusion : Moins de cérémonie, même comportement
[5:14 - 5:33] Les usings globaux sont une petite fonctionnalité qui rapporte au cours de la durée de vie d'un projet. Chaque fichier qui ne porte plus cinq lignes d'importations redondantes est un fichier qui s'ouvre sur le code réel plus rapidement, et une modification à un namespace partagé se fait en un seul endroit au lieu de dizaines. Le même soin qui entre dans les alias de type et la famille plus large des using s'applique ici : utilisez-le là où le gain de lisibilité est clair, et gardez le fichier central suffisamment petit pour que le prochain développeur puisse l'analyser d'un seul coup d'œil.
Conclusion
[5:14 - 5:33] Les usings globaux remplacent les lignes using par fichier par des directives à l'échelle du projet, la variante using global statique supprime le préfixe de classe des appels de membres statiques, et un seul fichier Usings.cs à la racine du projet est la convention qui le garde découvrable. La fonctionnalité est à opt-in et additive, donc son adoption sur une base de code existante est incrémentielle.
Conseil Exemple : Lorsque vous activez les usings implicites via <ImplicitUsings>enable</ImplicitUsings> dans votre .csproj, le SDK ajoute automatiquement un ensemble sélectionné de usings globaux (comme System, System.Linq, et System.Collections.Generic) sans que vous les écriviez. Associez cela avec votre propre Usings.cs pour des importations spécifiques au projet et le haut de chaque fichier devient sensiblement plus court.
Regardez la vidéo complète sur sa chaîne YouTube et obtenez plus d'informations sur la structure moderne des projets C# dans la série de formations de 10 minutes.
