![](https://www.developpez.com/images/logos/c-sharp.png)
Selon une l'équipe de Microsoft en charge, C# 13 commence à prendre forme avec des fonctionnalités axées sur la flexibilité, les performances et l'amélioration des fonctionnalités pour une utilisation quotidienne. C# est construit de manière ouverte et lors de la Microsoft Build, Microsoft a donné un aperçu de ce qui allait arriver dans C# 13.
Vous pouvez trouver les derniers aperçus de C# 13 dans le dernier aperçu de .NET 9 (depuis l'aperçu 6) et dans le dernier aperçu de Visual Studio 2022-17.11. Pour accéder aux fonctionnalités de prévisualisation, définissez votre version de langue sur preview dans votre fichier de projet :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <!--other settings--> <LangVersion>preview</LangVersion> <!--other settings--> </PropertyGroup> </Project> |
Présentation rapide des mise à jour et des nouvelles fonctionnalités :
- Amélioration de la collection de paramètres pour une plus grande flexibilité
- Objet de verrouillage
- Amélioration de l'opérateur d'indexation
- Séquence d'échappement \e
- Propriétés partielles
- Amélioration des types naturels de groupes de méthodes
- ref et unsafe dans les méthodes asynchrones et les itérateurs
- Mise à jour sur les types d'extension
Collections params
C# 13 étend params à tout type pouvant être construit via une expression de collection. Cela ajoute de la flexibilité, que vous écriviez une méthode ou que vous l'appeliez.
Lorsque le mot-clé params apparaît devant un paramètre, les appels à la méthode peuvent fournir une liste délimitée par des virgules de zéro ou plusieurs valeurs. Ce qui suit fonctionne dans toutes les versions de C# :
Code : | Sélectionner tout |
1 2 3 4 5 6 | public void WriteNames(params string[] names) => Console.WriteLine(String.Join(", ", names)); WriteNames("Mads", "Dustin", "Kathleen"); WriteNames(new string[] {"Mads", "Dustin", "Kathleen"}); // Both of these Would output: Mads, Dustin, Kathleen |
À partir de C# 13, les paramètres params peuvent être de n'importe quel type pris en charge pour les expressions de collection. Par exemple :
Code : | Sélectionner tout |
1 2 | public void WriteNames(params List<string> names) => Console.WriteLine(String.Join(", ", names)); |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public void WriteNames(params IEnumerable<string> names) => Console.WriteLine(String.Join(", ", names)); var persons = new List<Person> { new Person("Mads", "Torgersen"), new Person("Dustin", "Campbell"), new Person("Kathleen", "Dollard") }; // All of the following output: Mads, Dustin, Kathleen WriteNames("Mads", "Dustin", "Kathleen"); WriteNames(persons.Select(person => person.FirstName)); WriteNames(from p in persons select p.FirstName); |
Résolution des surcharges
Lors de la création d'une méthode, vous pouvez fournir plusieurs surcharges de params. Par exemple, l'ajout d'une surcharge IEnumerable<T> prend en charge LINQ et l'ajout d'une surcharge ReadOnlySpan<T> ou Span<T> réduit les allocations, ce qui peut améliorer les performances.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 | public void WriteNames(params string[] names) => Console.WriteLine(String.Join(", ", names)); public void WriteNames(params ReadOnlySpan<string> names) => Console.WriteLine(String.Join(", ", names)); public void WriteNames(params IEnumerable<string> names) => Console.WriteLine(String.Join(", ", names)); |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 | // IEnumerable overload is used WriteNames(persons.Select(person => person.FirstName)); // array overload is used WriteNames(new string[] {"Mads", "Dustin", "Kathleen"}); // most efficient overload is used: currently ReadOnlySpan WriteNames("Mads", "Dustin", "Kathleen"); |
Objet lock
.NET 9 inclut un nouveau type System.Threading.Lock pour l'exclusion mutuelle qui peut être plus efficace que le verrouillage sur une instance System.Object arbitraire. La proposition de type System.Threading.Lock contient plus d'informations sur ce type et sur les raisons de sa création. Au fil du temps, ce type devrait devenir le mécanisme principal utilisé pour la plupart des verrouillages dans le code C#.
C# 13 facilite l'utilisation de ce type. Lorsque le compilateur reconnaît que la cible de l'instruction lock est un objet System.Threading.Lock, C# génère désormais des appels à l'API System.Threading.Lock et fournit des avertissements pour les cas où une instance d'un Lock pourrait être traitée de manière incorrecte comme un object normal.
Cette mise à jour signifie que la syntaxe familière de l'instruction de véroullage tire parti des nouvelles fonctionnalités du runtime. Un code familier s'améliore avec un minimum de changements. Il suffit de changer le TargetFramework de votre projet en .NET 9 et de changer le type du verrou d'objet en System.Threading.Lock :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class MyClass { private object myLock = new object(); public void MyMethod() { lock (myLock) { // Your code } } } public class MyClass { // The following line is the only change private System.Threading.Lock myLock = new System.Threading.Lock(); public void MyMethod() { lock (myLock) { // Your code } } } |
Index à partir de la fin dans les initialisateurs
L'opérateur d'indexation ^ permet d'indiquer une position dans une collection dénombrable par rapport à la fin de la collection. Il fonctionne désormais dans les initialisateurs :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Program { static void Main() { var x = new Numbers { Values = { [1] = 111, [^1] = 999 // Works starting in C# 13 } // x.Values[1] is 111 // x.Values[9] is 999, since it is the last element }; } } class Numbers { public int[] Values { get; set; } = new int[10]; } |
Séquence d'échappement \e
C# 13 introduit une nouvelle séquence d'échappement pour le caractère que vous connaissez sous le nom de ESCAPE ou ESC. Auparavant, vous deviez taper ce caractère sous la forme d'une variante de \u001b. Cette nouvelle séquence est particulièrement pratique pour interagir avec des terminaux utilisant les codes d'échappement VT100/ANSI de System.Console. Par exemple :
Code : | Sélectionner tout |
1 2 3 4 5 | // Prior to C# 13 Console.WriteLine("\u001b[1mThis is a bold text\u001b[0m"); // With C# 13 Console.WriteLine("\e[1mThis is a bold text\e[0m"); |
Propriétés partielles
C# 13 ajoute les propriétés partielles. Tout comme les méthodes partielles, leur objectif principal est de prendre en charge les générateurs de sources. Les méthodes partielles sont disponibles depuis de nombreuses versions et ont été améliorées en C# 9. Les propriétés partielles ressemblent beaucoup à leurs homologues de méthodes partielles.
Par exemple, à partir de .NET 7 (C# 12), le générateur de source d'expressions régulières crée un code efficace pour les méthodes :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | [GeneratedRegex("abc|def")] private static partial Regex AbcOrDefMethod(); if (AbcOrDefMethod().IsMatch(text)) { // Take action with matching text } |
Code : | Sélectionner tout |
1 2 3 4 5 6 7 | [GeneratedRegex("abc|def")] private static partial Regex AbcOrDefProperty { get; }; if (AbcOrDefProperty.IsMatch(text)) { // Take action with matching text } |
Amélioration du type naturel des groupes de méthodes
Le type naturel d'une expression est le type déterminé par le compilateur, par exemple lorsque le type est assigné à var ou Delegate. C'est simple lorsqu'il s'agit d'un type simple. En C# 10, ils ont ajouté la prise en charge des groupes de méthodes. Les groupes de méthodes sont utilisés lorsque vous incluez le nom d'une méthode sans parenthèses dans un délégué :
Code : | Sélectionner tout |
1 2 | Todo GetTodo() => new(Id: 0, Name: "Name"); var f = GetTodo; // the type of f is Func<ToDo> |
allows ref struct
C# 13 ajoute une nouvelle façon de spécifier les capacités pour les paramètres de type générique. Par défaut, les paramètres de type ne peuvent pas être ref struct. C# 13 vous permet de spécifier qu'un paramètre de type peut être une ref struct et applique les règles appropriées. Alors que d'autres contraintes génériques limitent l'ensemble des types pouvant être utilisés comme paramètre de type, cette nouvelle spécification élargit les types autorisés. Nous considérons qu'il s'agit d'une anti-contrainte puisqu'elle supprime plutôt qu'elle n'ajoute une restriction. La syntaxe allows ref struct dans la clause where, où allows indique cette expansion de l'usage :
Code : | Sélectionner tout |
1 2 3 4 5 6 | T Identity<T>(T p) where T : allows ref struct => p; // Okay Span<int> local = Identity(new Span<int>(new int[10])); |
ref et unsafe dans les méthodes async et les itérateurs
Avant C# 13, les méthodes itératrices (méthodes qui utilisent yield return) et les méthodes async ne pouvaient pas déclarer de variables locales ref, ni avoir un contexte unsafe.
En C# 13, les méthodes async peuvent déclarer des variables locales ref ou des variables locales de type ref struct. Ces variables ne peuvent pas être conservées au-delà d'une limite await ou d'une limite yield return.
De la même manière, C# 13 autorise les contextes unsafe dans les méthodes d'itérateur. Cependant, toutes les instructions yield return et await doivent être dans des contextes sûrs. Ces restrictions assouplies vous permettent d'utiliser les variables locales ref et les types ref struct dans un plus grand nombre d'endroits.
Une mise à jour sur les types d'extension sera disponibles dans les premiers aperçus de C# 14 (NET 10).
Source : Annonce C# 13
Et vous ?
![:fleche:](https://www.developpez.net/forums/images/smilies/fleche.gif)
Voir aussi :
![:fleche:](https://www.developpez.net/forums/images/smilies/fleche.gif)
![:fleche:](https://www.developpez.net/forums/images/smilies/fleche.gif)
![:fleche:](https://www.developpez.net/forums/images/smilies/fleche.gif)