Cet article fait partie d’une série d’articles sur les apports fonctionnels de C# 10.0.
A partir de C# 10 et .NET 6, 2 fonctionnalités permettent de limiter la répétition des using <namespace>
en tête des fichiers C#:
- l’opérateur
global
et - la propriété
ImplicitUsings
.
Ces 2 fonctionnalités visent à déclarer les namespaces une fois par projet de façon à ne pas avoir à répéter les déclarations dans tous les fichiers .cs
.
Mot-clé global
A partir de C# 10, le mot-clé global
a désormais 2 significations:
- Utilisé en tant que mot-clé de cette façon
global::
il est un alias pour désigner le namespace global par opposition à un namespace déclaré par le développeur dans son code. Le namespace global contient des types qui ne sont pas déclarés dans un namespace nommé.global::
permet de différencier 2 namespaces qui auraient le même nom et dont un des 2 ferait partie de code déclaré en dehors du code du développeur.Par exemple, si on considère le code suivant:
namespace CS10_Example.System { public class Object { } }
On peut utiliser cette classe de cette façon:
namespace CS10_Example { internal class GlobalKeywordExample { public void ExecuteMe() { var exampleInstance = new System.Object(); } } }
System.Object
désigne la classeCS10_Example.System.Object
. Si on veut instancier l’objetObject
provenant du framework, on ne peut pas le faire sans passer par le mot-cléglobal
:var exampleInstance = new System.Object(); var objectInstance = new global::System.Object();
Dans cet exemple
global::System.Object
désigne bien l’objetobject
du framework. - A partir de C# 10,
global
est aussi utilisé en tant que modificateur de portée lorsqu’on déclare des namespaces. Lorsqueglobal
précède une déclarationusing <namespace>
, il permet d’étendre la portée de la déclaration à la portée du projet.
Ainsi si on déclare l’utilisation d’un namespace dans un fichier, en faisant précéder la déclaration avecglobal
, la déclaration aura pour portée le projet:global using CS10_Example.System;
On peut aussi déclarer de façon globale des alias avec une syntaxe du type:
global using Env = System.Environment;
L’intérêt est d’éviter de multiplier les déclarations des mêmes namespaces dans plusieurs fichiers
.cs
du projet. Une seule déclaration suffit.
Propriété ImplicitUsings
ImplicitUsings
est une propriété du .csproj
qui est apparu à partir de .NET 6 qui permet d’ajouter des déclarations globales de namespace dans un .csproj
en fonction du type de projet créé. Si la propriété est activée, alors à la compilation, des déclarations du type suivant seront rajoutées:
global using global::<namespace du framework>;
Ces déclarations ont pour but d’éviter la multiplication des using <namespace>
dans chaque fichier d’un projet.
Dans la pratique suivant le type du projet, les déclarations sont rajoutées dans un fichier se trouvant dans:
<répertoire du projet>\obj\<configuration>\<target framework>\<nom du projet>.GlobalUsings.g.cs
Par exemple si le projet s’appelle Cs10Example
, que la configuration de compilation soit Debug
et que le framework cible net6.0
alors le fichier sera:
Cs10Example\obj\Debug\net6.0\Cs10Example.GlobalUsings.g.cs
Le contenu de ce fichier dépend du type de projet indiqué dans le .csproj
:
<Project Sdk="Microsoft.NET.Sdk.Web">
...
</Project>
Ainsi pour une application Console générée avec:
dotnet new console -o <nom du projet>
L’entête du .csproj
sera:
<Project Sdk="Microsoft.NET.Sdk">
...
</Project>
Et les déclarations des namespaces seront:
global using global::System
global using global::System.Collections.Generic
global using global::System.IO
global using global::System.Linq
global using global::System.Net.Http
global using global::System.Threading
global using global::System.Threading.Tasks
Pour une application Web générée avec:
dotnet new web -o <nom du projet>
L’entête du .csproj
sera:
<Project Sdk="Microsoft.NET.SdkWeb”>
...
</Project>
En plus des déclarations précédentes, les namespaces implicites seront:
global using global::System.Net.Http.Json
global using global::Microsoft.AspNetCore.Builder
global using global::Microsoft.AspNetCore.Hosting
global using global::Microsoft.AspNetCore.Http
global using global::Microsoft.AspNetCore.Routing
global using global::Microsoft.Extensions.Configuration
global using global::Microsoft.Extensions.DependencyInjection
global using global::Microsoft.Extensions.Hosting
global using global::Microsoft.Extensions.Logging
On peut trouver une liste plus exhaustive des namespaces implicites sur learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#implicit-using-directives.
Valeur par défaut
Pour tous les nouveaux projets ciblant .NET 6 et supérieur, la propriété ImplicitUsings
est présente dans le .csproj
avec la valeur enable
:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- ... -->
<ImplicitUsings>enable</ImplicitUsings>
<!-- ... -->
</PropertyGroup>
</Project>
Si la propriété ImplicitUsings
n’est pas présente dans le fichier .csproj
, la fonctionnalité est désactivée par défaut.
Désactiver ImplicitUsings
Pour désactiver ImplicitUsings
, on peut soit supprimer la propriété du fichier .csproj
(la valeur par défaut est désactivée), soit explicitement la désactiver avec la valeur disable
:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- ... -->
<ImplicitUsings>disable</ImplicitUsings>
<!-- ... -->
</PropertyGroup>
</Project>
Ajouter ou supprimer une déclaration using globale dans le .csproj
Il est possible d’ajouter ou de supprimer une déclaration using
globale directement dans le fichier .csproj
.
Pour effectuer une déclaration using
globale dans le .csproj
pour supprimer un namespace particulier, on peut utiliser la syntaxe:
<Project Sdk="Microsoft.NET.Sdk.Web">
</PropertyGroup>
<!-- ... -->
<ItemGroup>
<Using Remove="System.Threading.Tasks" />
</ItemGroup>
</Project>
Par opposition, pour effectuer une déclaration globale permettant de rajouter un namespace particulier:
<Project Sdk="Microsoft.NET.Sdk.Web">
</PropertyGroup>
<!-- ... -->
<ItemGroup>
<Using Include="System.Net.Http" />
</ItemGroup>
</Project>
- global modifier: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive#global-modifier
- :: operator – the namespace alias operator: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/namespace-alias-qualifier
- Welcome to C# 10: https://devblogs.microsoft.com/dotnet/welcome-to-csharp-10/
- Implicit using directives: https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#implicit-using-directives
- Implicit Usings in .NET 6: https://www.hanselman.com/blog/implicit-usings-in-net-6
- What is global::?: https://stackoverflow.com/questions/15022441/what-is-global
- Implicit Using Statements In .NET 6: https://dotnetcoretutorials.com/implicit-using-statements-in-net-6