La semaine dernière, Microsoft a annoncé la disponibilité officielle de C# 8.0 dans la version .NET Core 3.0, simultanément sur .NET Conf 2019 et sur son blog de développement. Les nouvelles fonctionnalités du langage incluent les nullable reference types, les flux asynchrones, les membres d'interface par défaut et les nouveaux patterns de code. Toutes les nouvelles fonctionnalités sont prises en charge dans Visual Studio 2019.
Les Nullable reference types sont l'une des fonctionnalités les plus importantes de la nouvelle version. Ils sont destinés à éviter les situations liées aux exceptions de référence null via l'utilisation de règles de syntaxe spécifiques : le développeur doit explicitement indiquer si une variable donnée peut avoir une valeur null. Dans ce cas, le nom du type dans la déclaration de variable doit être suivi d'un ?
(de la même manière que les nullable value types ) :
string? foo;
Si la variable n'a pas ?
ajouté au nom du type, elle est considérée comme un type de référence non nullable. Dans ce cas, le compilateur appliquera des règles non nullables : la variable doit être initialisée avec une valeur non nulle et la variable ne peut jamais être affectée de la valeur null. Il est possible (bien que cela ne soit pas recommandé dans la plupart des cas) de remplacer ce comportement par l'opérateur null-forgiving !
après un nom de variable :
foo!.Length;
Il est également possible d'utiliser des nullable contexts pour contrôler si des avertissements Nullables sont émiss ou si les annotations nullables ont un effet. Les nullable contextx peuvent être spécifiés au niveau du projet ou dans le fichier de code source avec les directives de pré-traitement #nullable
et #pragma warning
. En outre, un type peut avoir l'une des quatre valeurs nuls suivantes : Oblivious, nonnullable, nullable et unknown. Des valeurs de nullité différentes déclenchent différents comportements du compilateur. La spécification complète pour les types de référence nullable peut être trouvée ici.
Une autre caractéristique importante est l'introduction des flux asynchrones (asynchronous streams). L'objectif de cette nouvelle fonctionnalité est d'introduire la prise en charge de méthodes à la fois itératives et asynchrones. De telles méthodes peuvent être utilisées dans des scénarios où il est nécessaire de consommer ou de produire des flux de résultats continus (par exemple, à partir d'un périphérique IoT ou d'un service dans le cloud).
Les flux asynchrones (Async streams) sont implémentés via les interfaces IAsyncEnumerable<T>
et IAsyncEnumerator<T>
, qui peuvent être utilisées conjointement avec la fonctionnalité async/wait ( introduite à l'origine en C # 5.0 ). Une méthode qui renvoie un flux asynchrone doit être déclarée avec le modificateur async
et doit également avoir l'une des nouvelles interfaces comme type de retour. Il doit également contenir des instructions yield return
pour renvoyer des éléments successifs dans le flux asynchrone.
L'exemple suivant est contenu dans la documentation officielle de Microsoft. Il implémente une méthode qui génère une séquence de 0 à 19, en attendant 100 ms entre chaque génération :
public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()
{
for (int i = 0; i < 20; i++)
{
await Task.Delay(100);
yield return i;
}
}
Vous trouverez plus de détails sur les flux asynchrones dans la spécification officielle du langage.
Les membres d'interface par défaut (Default interface members) sont une fonctionnalité qui permet au développeur d'ajouter des membres aux interfaces et de fournir une implémentation à ces membres (permettant ainsi aux méthodes d'utiliser des interfaces avec des implémentations concrètes). L'objectif est de donner plus de flexibilité aux auteurs d'API afin qu'ils puissent ajouter des méthodes à une interface existante sans rompre la compatibilité avec les versions précédentes. Cette fonctionnalité est similaire aux méthodes par défaut (Default methods) de Java.
C# 8.0 ajoute également deux nouveaux patterns de code : recursive pattern matching et un pattern lié à l'instruction using
. Les patterns récursifs, en un mot, permettent aux patterns de contenir d'autres patterns, comme dans l'exemple ci-dessous (également dans la documentation officielle de Microsoft ) :
IEnumerable<string> GetEnrollees()
{
foreach (var p in People)
{
if (p is Student { Graduated: false, Name: string name }) yield return name;
}
}
Le pattern Student { Graduated: false, Name: string name }
vérifie que Person
est un Student
, puis applique le pattern constant false à leur propriété pour voir si elles sont toujours inscrites, et le pattern string name à leur propriété pour obtenir leur nom (si non-nul). Ainsi, si p
est un Student
, n'a pas obtenu son diplôme et a un nom non nul, nous retournons ce nom.
Le nouveau pattern à propos de l'instruction using
lui permet d'être ajoutée à une déclaration de variable locale. Dans ce cas, la durée de vie de la section locale using
s'étendra jusqu'à la fin de la portée dans laquelle elle est déclarée. S'il y a plus d'une section locale using
, elles seront éliminées dans l'ordre inverse de leur déclaration :
{
using var foo1 = new FileStream("...");
using var foo2 = new FileStream("...");
...
// Dispose foo2
// Dispose foo1
}
Une autre fonctionnalité ajoutée à propose de l'instruction using
est la notion de pattern disposable, c'est-à-dire un type qui possède une méthode d'instance Dispose accessible. Les types qui suivent ce modèle peuvent participer à une instruction using sans avoir à implémenter IDisposable
:
class Bar
{
public void Dispose() { ... }
}
using (var foo = new Bar())
{
// statements
}
Les autres fonctionnalités ajoutées dans C# 8.0 incluent des modifications dans la syntaxe des instructions switch et l'ajout des target-typed new-expressions, qui permettent l'omission des déclarations de type lors de la création de nouveaux objets dans des contextes dans lesquels le type est déjà indiqué :
Vector2[] vectors = { new (1, 1), new (2, -1) };
Un résumé de toutes les nouvelles fonctionnalités est disponible ici, et la proposition complète des spécifications de C# 8.0 se trouve ici. Les sessions techniques présentées lors de la conférence .NET 2019 mettant en avant les nouvelles fonctionnalités linguistiques sont également disponibles sur YouTube (ici et ici). C# 8.0 est inclus dans toutes les versions de Visual Studio 2019.