Nouveautés dans C# 10

C# 10 ajoute les fonctionnalités et améliorations suivantes au langage C# :

C# 10 est pris en charge sur .NET 6. Pour plus d’informations, consultez Contrôle de version du langage C#.

Vous pouvez télécharger la dernière version du kit SDK .NET 6 sur la page de téléchargements .NET. Vous avez également la possibilité de télécharger Visual Studio 2022, qui inclut la version 6 du kit SDK .NET.

Notes

Vos commentaires sur ces fonctionnalités nous intéressent. Si vous rencontrez des problèmes avec l’une de ces nouvelles fonctionnalités, créez un nouveau problème dans le référentiel dotnet/roslyn.

Structs d’enregistrement

Vous pouvez déclarer des enregistrements de type valeur à l’aide des déclarations record struct ou readonly record struct. Vous pouvez maintenant clarifier que record est un type référence avec la déclaration record class.

Améliorations des types de structure

C# 10 présente les améliorations suivantes relatives aux types de structure :

  • Vous pouvez déclarer un constructeur sans paramètre d’instance dans un type de structure et initialiser un champ ou une propriété d’instance à sa déclaration. Pour plus d’informations, consultez la section Initialisation de struct et valeurs par défaut de l’article Types de structure.
  • Un opérande de gauche de l’expression with peut être de n’importe quel type de structure ou d’un type anonyme (référence).

Gestionnaire de chaînes interpolées

Vous pouvez créer un type qui génère la chaîne résultante à partir d’une expression de chaîne interpolée. Les bibliothèques .NET utilisent cette fonctionnalité dans un grand nombre d’API. Vous pouvez en créer un en suivant ce didacticiel.

Directives using globales

Vous pouvez ajouter le modificateur global à n’importe quel à l’aide de la directive pour indiquer au compilateur que la directive s’applique à tous les fichiers sources de la compilation. Il s’agit généralement de tous les fichiers sources d’un projet.

Déclaration d’espace de noms délimitée aux fichiers

Vous pouvez utiliser une nouvelle forme de déclaration namespace pour déclarer que toutes les déclarations suivantes sont membres de l’espace de noms déclaré :

namespace MyNamespace;

Cette nouvelle syntaxe enregistre à la fois l’espace horizontal et vertical pour les déclarations namespace.

Modèles de propriétés étendues

À compter de C# 10, vous pouvez référencer des propriétés ou des champs imbriqués dans un modèle de propriété. Par exemple, un modèle du formulaire

{ Prop1.Prop2: pattern }

est valide en C# 10 et versions ultérieures et équivalent à

{ Prop1: { Prop2: pattern } }

est valide en C# 8.0 et versions ultérieures.

Pour plus d’informations, consultez la section relative à la proposition de fonctionnalité modèles de propriétés étendues . Pour plus d’informations sur un modèle de propriété, consultez la section Modèle de propriété de l’article Modèles.

Améliorations apportées aux expressions lambda

C# 10 inclut de nombreuses améliorations à la gestion des expressions lambda :

  • Les expressions lambda peuvent avoir un type naturel, où le compilateur peut déduire un type délégué à partir du groupe d’expressions lambda ou de méthodes.
  • Les expressions lambda peuvent déclarer un type de retour lorsque le compilateur ne peut pas le déduire.
  • Les attributs peuvent être appliqués aux expressions lambda.

Grâce à ces fonctionnalités, les expressions ressemblent davantage aux méthodes et aux fonctions locales. Elles facilitent l’utilisation d’expressions lambda sans déclarer une variable d’un type délégué et leur fonctionnement est plus transparent avec les nouvelles API minimales ASP.NET Core.

Chaînes interpolées constantes

En C# 10, les chaînes const peuvent être initialisées à l’aide de l’interpolation de chaîne si tous les espaces réservés sont eux-mêmes des chaînes constantes. L’interpolation de chaînes peut créer des chaînes de constantes plus lisibles lorsque vous générez de telles chaînes pour les utiliser dans votre application. Les expressions d’espace réservé ne peuvent pas être des constantes numériques, car ces constantes sont converties en chaînes au moment de l’exécution. La culture actuelle en la matière peut affecter leur représentation en tant que chaîne. Pour en savoir plus, consultez la référence de langage sur les expressions const.

Les types d’enregistrements peuvent sceller ToString

En C# 10, vous pouvez ajouter le modificateur sealed lorsque vous remplacez ToString dans un type d’enregistrement. Le scellement de la méthode ToString empêche le compilateur de synthétiser une méthode ToString pour tous les types d’enregistrements dérivés. Un sealedToString garantit que tous les types d’enregistrements dérivés utilisent la méthode ToString définie dans un type d’enregistrement de base commun. Pour plus d’informations sur cette fonctionnalité, consultez l’article sur les enregistrements.

Affectation et déclaration dans la même déconstruction

Ce changement supprime une restriction des versions antérieures de C#. Auparavant, une déconstruction peut affecter toutes les valeurs à des variables existantes ou initialiser des variables nouvellement déclarées :

// Initialization:
(int x, int y) = point;

// assignment:
int x1 = 0;
int y1 = 0;
(x1, y1) = point;

C# 10 supprime cette restriction :

int x = 0;
(x, int y) = point;

Amélioration de l’affectation définitive

Avant C# 10, il était fréquent que l’affectation définie et l’analyse de l’état null produisent des avertissements qui étaient des faux positifs. Ces comparaisons impliquent généralement des comparaisons avec des constantes booléennes, l’accès à une variable uniquement dans les instructions true ou false dans une instruction if et les expressions de coalescence null. Ces exemples ont généré des avertissements dans les versions précédentes de C#, mais pas en C# 10 :

string representation = "N/A";
if ((c != null && c.GetDependentValue(out object obj)) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ?.
if (c?.GetDependentValue(out object obj) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ??
if (c?.GetDependentValue(out object obj) ?? false)
{
   representation = obj.ToString(); // undesired error
}

L’impact principal de cette amélioration est que les avertissements relatifs à l’affectation définie et l’analyse de l’état null sont plus précis.

Autoriser l’attribut AsyncMethodBuilder sur les méthodes

En C# 10 et versions ultérieures, vous pouvez spécifier un générateur de méthodes asynchrone différent pour une seule méthode, en plus de spécifier le type de générateur de méthodes pour toutes les méthodes qui retournent un type de tâche donné. Un générateur de méthode asynchrone personnalisé permet des scénarios avancés de réglage des performances dans lesquels une méthode donnée peut tirer parti d’un générateur personnalisé.

Pour plus d’informations, consultez la section sur AsyncMethodBuilder dans l’article sur les attributs lus par le compilateur.

Diagnostics d’attribut CallerArgumentExpression

Vous pouvez utiliser le paramètre System.Runtime.CompilerServices.CallerArgumentExpressionAttribute pour spécifier un paramètre que le compilateur remplace par la représentation textuelle d’un autre argument. Cette fonctionnalité permet aux bibliothèques de créer des diagnostics plus spécifiques. Le code suivant teste une condition. Si la condition est fausse, le message d’exception contient la représentation textuelle de l’argument passé à condition :

public static void Validate(bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
    if (!condition)
    {
        throw new InvalidOperationException($"Argument failed validation: <{message}>");
    }
}

Vous pouvez en savoir plus sur cette fonctionnalité dans l’article sur les attributs d’informations de l’appelant dans la section de référence du langage.

Pragma amélioré #line

C# 10 prend en charge un nouveau format pour le pragma #line. Vous n’utiliserez probablement pas le nouveau format, mais vous verrez ses effets. Les améliorations permettent une sortie plus fine dans des langages spécifiques au domaine (DSL) comme Razor. Le moteur Razor utilise ces améliorations pour améliorer l’expérience de débogage. Vous trouverez des débogueurs qui peuvent mettre en évidence votre source Razor plus précisément. Pour en savoir plus sur la nouvelle syntaxe, consultez l’article sur les directives de préprocesseur dans le guide de référence du langage. Vous pouvez également lire les spécifications de fonctionnalités pour les exemples Razor.