Nouveautés de C# 12
C# 12 inclut les nouvelles fonctionnalités suivantes. Vous pouvez essayer ces fonctionnalités à l’aide de la dernière version visual Studio 2022 ou du SDK .NET 8.
Constructeurs principaux - Introduits dans Visual Studio 2022 version 17.6 Preview 2.
Expressions de collection - Introduites dans Visual Studio 2022 version 17.7 Preview 5.
tableaux en ligne - Introduit dans Visual Studio 2022 version 17.7 Preview 3.
paramètres facultatifs dans les expressions lambda - Introduit dans Visual Studio 2022 version 17.5 Preview 2.
ref readonly
paramètres - Introduit dans Visual Studio 2022 version 17.8 Preview 2.Alias any type - Introduit dans Visual Studio 2022 version 17.6 Preview 3.
attribut expérimental - Introduit dans Visual Studio 2022 version 17.7 Preview 3.
Intercepteurs - fonctionnalité Preview introduite dans Visual Studio 2022 version 17.7 Preview 3.
C# 12 est pris en charge sur .NET 8. Pour plus d'informations, consultez Contrôle de version du langage C#.
Vous pouvez télécharger le kit SDK .NET 8 le plus récent à partir de la page de téléchargements .NET. Vous pouvez également télécharger Visual Studio 2022, qui inclut le Kit de développement logiciel (SDK) .NET 8.
Remarque
Nous sommes intéressés par vos commentaires sur ces fonctionnalités. 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.
Constructeurs principaux
Vous pouvez désormais créer des constructeurs principaux dans n'importe quel class
et struct
. Les constructeurs principaux ne sont plus limités aux types record
. Les paramètres de constructeur principal se trouvent dans l'étendue de l'ensemble du corps de la classe. Pour vous assurer que tous les paramètres du constructeur principal sont assurément attribués, tous les constructeurs explicitement déclarés doivent appeler le constructeur principal à l'aide de la syntaxe this()
. L’ajout d’un constructeur principal à un class
empêche le compilateur de déclarer un constructeur sans paramètre implicite. Dans struct
, le constructeur sans paramètre implicite initialise tous les champs, notamment les paramètres de constructeur principal selon le modèle 0 bit.
Le compilateur génère des propriétés publiques pour les paramètres de constructeur principal uniquement dans les types record
, record class
ou record struct
types. Les classes et structs non enregistrés peuvent ne pas toujours vouloir ce comportement pour les paramètres du constructeur principal.
Vous pouvez en savoir plus sur les constructeurs principaux dans le didacticiel pour explorer les constructeurs principaux et dans l’article sur les constructeurs d’instance .
Expressions de collection
Les expressions de collection introduisent une nouvelle syntaxe terse pour créer des valeurs de collection courantes. L’incorporation d’autres collections dans ces valeurs est possible à l’aide d’un élément de propagation ..e
.
Plusieurs types semblables à des collections peuvent être créés sans nécessiter de support BCL externe. Ces types sont les suivants :
- Types de tableaux, tels que
int[]
. - System.Span<T> et System.ReadOnlySpan<T>.
- Les types qui prennent en charge les initialisateurs de collection, tels que System.Collections.Generic.List<T>.
Les exemples suivants montrent les utilisations d’expressions de collection :
// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];
// Create a list:
List<string> b = ["one", "two", "three"];
// Create a span
Span<char> c = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];
// Create a jagged 2D array:
int[][] twoD = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
// Create a jagged 2D array from variables:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[][] twoDFromVariables = [row0, row1, row2];
L'élément spread, ..e
dans une expression de collection ajoute tous les éléments de cette expression. L'argument doit être un type de collection. Les exemples suivants montrent comment fonctionne l’élément de propagation :
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[] single = [.. row0, .. row1, .. row2];
foreach (var element in single)
{
Console.Write($"{element}, ");
}
// output:
// 1, 2, 3, 4, 5, 6, 7, 8, 9,
L’élément de propagation évalue chaque élément de l’expression d’énumérations. Chaque élément est inclus dans la collection de résultats.
Vous pouvez utiliser des expressions de collection partout où vous avez besoin d’une collection d’éléments. Ils peuvent spécifier la valeur initiale d’une collection ou être passés en tant qu’arguments aux méthodes qui acceptent des types de collection. Vous pouvez en savoir plus sur les expressions de collection dans l’article de référence du langage sur les expressions de collection ou la spécification de fonctionnalité .
paramètres de ref readonly
C# a ajouté les paramètres in
comme moyen de passer des références en lecture seule. Les paramètres in
permettent l'utilisation de variables et de valeurs, et peuvent être utilisés sans aucune annotation sur les arguments.
L’ajout de paramètres ref readonly
permet une plus grande clarté pour les API qui peuvent utiliser des paramètres ref
ou des paramètres in
:
- Les API créées avant l’introduction de
in
peuvent utiliserref
même si l’argument n’est pas modifié. Ces API peuvent être mises à jour avecref readonly
. Il ne s'agit pas d'un changement radical pour les appelants, comme ce serait le cas si le paramètreref
était remplacé parin
. Par exemple, System.Runtime.InteropServices.Marshal.QueryInterface. - Les API qui prennent un paramètre
in
, mais nécessitent logiquement une variable. Une expression de valeur ne fonctionne pas. Par exemple, System.ReadOnlySpan<T>.ReadOnlySpan<T>(T). - Les API qui utilisent
ref
, car elles nécessitent une variable, mais ne mutent pas cette variable. Par exemple, System.Runtime.CompilerServices.Unsafe.IsNullRef.
Pour en savoir plus sur les paramètres ref readonly
, consultez l'article sur les modificateurs de paramètres dans la référence du langage, ou la spécification de la fonctionnalité ref readonly parameters.
Paramètres lambda par défaut
Vous pouvez maintenant définir des valeurs par défaut pour les paramètres sur les expressions lambda. La syntaxe et les règles sont identiques à l’ajout de valeurs par défaut pour les arguments à n’importe quelle méthode ou fonction locale.
Vous pouvez en savoir plus sur les paramètres par défaut sur les expressions lambda dans l’article sur expressions lambda.
Alias de n'importe quel type
Vous pouvez utiliser la directive d’alias using
pour alias n’importe quel type, pas seulement les types nommés. Cela signifie que vous pouvez créer des alias sémantiques pour les types tuple, les types de tableaux, les types de pointeur ou d’autres types non sécurisés. Pour plus d’informations, consultez la spécification de fonctionnalité . Pour obtenir un exemple de procédure pas à pas de refactorisation, consultez Refactoriser votre code à l’aide d’alias n’importe quel type sur le blog .NET.
Tableaux inline
Les tableaux inline sont utilisés par l’équipe runtime et d’autres auteurs de bibliothèque pour améliorer les performances de vos applications. Les tableaux inline permettent au développeur de créer un tableau de taille fixe dans un type struct
. Un struct avec une mémoire tampon inline doit fournir des caractéristiques de performances similaires à une mémoire tampon de taille fixe non sécurisée. Vous ne déclarez probablement pas vos propres tableaux inline, mais vous les utilisez de manière transparente lorsqu’ils sont exposés en tant qu’objets System.Span<T> ou System.ReadOnlySpan<T> à partir d’API runtime.
Un tableau inline est déclaré similaire à la struct
suivante :
[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
private int _element0;
}
Vous les utilisez comme n’importe quel autre tableau :
var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
buffer[i] = i;
}
foreach (var i in buffer)
{
Console.WriteLine(i);
}
La différence est que le compilateur peut tirer parti des informations connues sur un tableau inline. Vous pouvez utiliser les tableaux en ligne comme n'importe quel autre tableau. Pour plus d'informations sur la manière de déclarer des tableaux en ligne, consultez la référence du langage sur les types struct
.
Attribut expérimental
Les types, méthodes ou assemblys peuvent être marqués avec le System.Diagnostics.CodeAnalysis.ExperimentalAttribute pour indiquer une fonctionnalité expérimentale. Le compilateur émet un avertissement si vous accédez à une méthode ou un type annotés avec le ExperimentalAttribute. Tous les types inclus dans un assembly marqué avec l’attribut Experimental
sont expérimentaux. Vous pouvez en savoir plus dans l’article sur les attributs généraux lus par le compilateur, ou la spécification de fonctionnalité .
Intercepteurs
Avertissement
Les intercepteurs sont une fonctionnalité expérimentale, disponible en mode préversion avec C# 12. La fonctionnalité peut faire l'objet de changements majeurs ou d'une suppression dans une version ultérieure. Par conséquent, elles ne sont pas recommandées pour des applications en production ou publiées.
Pour utiliser des intercepteurs, le projet utilisateur doit spécifier la propriété <InterceptorsPreviewNamespaces>
. Il s’agit d’une liste d’espaces de noms autorisés à contenir des intercepteurs.
Par exemple : <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>
Un intercepteur est une méthode qui peut remplacer de manière déclarative un appel à une méthode interceptable par un appel à lui-même au moment de la compilation. Cette substitution se produit lorsque l’intercepteur déclare les emplacements sources des appels qu’il intercepte. Les intercepteurs offrent une capacité limitée à modifier la sémantique du code existant en ajoutant du nouveau code à une compilation, par exemple dans un générateur de code source.
Vous utilisez un intercepteur dans le cadre d’un générateur source à modifier, plutôt que d’ajouter du code à une compilation source existante. Le générateur source remplace les appels à une méthode interceptable par un appel à la méthode de l'intercepteur .
Si vous souhaitez expérimenter des intercepteurs, vous pouvez en savoir plus en lisant la spécification de fonctionnalité . Si vous utilisez la fonctionnalité, veillez à rester informé des modifications apportées à la spécification de fonctionnalité pour cette fonctionnalité expérimentale. Si la fonctionnalité est finalisée, nous ajouterons des conseils supplémentaires sur ce site.