Nouvelle fonctionnalités avec c# 8

La syntaxe d'un language comme le C# est un sujet soumis au changement. La meilleure source d'informations concernant l'évolution d'un language comme le C# se trouve sur GitHub.

Gestion des nulls :

Avec la version 8, la gestion des non nullable et des réferences des types nullables va évoluer. Le C# a deux types de variables : primitif et type référence. Les primitifs sont des types comme les int, char ou encore double. Ce sont des types qui ne peuvent pas prendre de valeurs null. La création d'un nouvel entier variable du type int donc, sans assigné de valeur cette variable aura la valeur 0 non null. Le c# 2.0 a introduit les versions nullables pour de multiples type primitifs en les dénotant de "?" ou int? Alors que les types références ont toujours pu prendre la valeur null comme les string qui ont une valeur null par défaut. Cela a le désavantage d'autoriser des nulls réferences qui se glissent alors dans nos applications.

En C# 8 cela optera pour une optimisation de la fonctionnalités sur les types références non nullables. La modification d'un concept de ce type sur un langage comme C# est assez difficile notamment car cela peut provoquer des erreurs de compilations qui auparavant fonctionnait très bien. C'est un besoin de trouver un moyen de créer cette fonctionnalité sans créer une surcharge insurmontable de travail pour les développeurs. Le design proposé pour atteindre ce but sera de définir au niveau du projet des settings pour include cette validation des références nullables. Une fois activée, les objets qui pourront prendre la valeur null devront utiliser le même opérateur ? que pour les types primitifs pouvant être nullable.

Ainsi le code :

String s = null;
Console.Write(s);

Deviendra :

String? s = null;
Console.Write(s);

 

C'est un élément du langage qui pour moi à du sens pour améliorer la qualité du code. Toutefois, cela va nécessiter un gros travail pour reprendre le code existant...

 

Classes lègères :

Une autre fonctionnalité intéressante pourra être le "Lightweight classes ou records". C'est une nouvelle manière de créer des classes très light représenter par des classes qui n'ont que des fields, assez proche finalement de nos objets poco. Ces classes faciliteront le mécanisme de comparaison entre les objets qui demande pour l'instant un peu de travail à chaque fois pour des classes qui n'en vaillent finalement pas la peine. 

La syntaxe ressemblera à cela :

class BankAccount(Guid Id, string Name, decimal Balance)

Et nous pourrons effectuer des tests d'égalités sans problème cette fois : a == b

Implémentation par défaut des interfaces :

Le versionning des interfaces est assez ennuyeuse car cela requiert de créer une nouvelle méthode sur l'interface qui devra être implémenter sur tous les objets qui implémentent cette interface. Etant donné que toutes les implémentations n'ont pas d'ancétres commun, ajouté une méthode à l'interface doit nécessiter d'être implémenté indépendament pour chaque classe.

L'implémentation par défaut autorise de spécifier une implémentation dans l'interface qui sera utilisée comme une fonction pour les méthodes existantes sur l'interface. Prenons l'exemple d'un compte bancaire nous pourrions avoir une interface de ce type :

public interface IBankAccountManager{
    void PerformTransaction(decimal amount, string reason);
}

Maintenant, pour des besoins de "praticités" nous aimerions exposer des fonctions pour gèrer le débit et le crédit sur le compte bancaire. Normalement, nous devrions ajouter cela à l'interface et aller implémenter ces méthodes sur les objets qui implémentent l'interface IBankAccounManager. Mais avec une implémentation par défaut cela donnera :

public interface IBankAccountManager{ 
  void PerformTransaction(decimal amount, string reason); 
  void PerformDebit(decimal amount, string reason){ 
    PerformTransaction(-1 * amount, $”Debit: {reason}”); 
  } 
 
  void PerformCredit(decimal amount, string reason){ 
    PerformTransaction(amount, $”Credit: {reason}”); 
  } 
}

Les implémentations par défaut des interfaces produisent une outil puissant pour étendre les interfaces sans avoir à dupliquer du code. Il faudra voir en pratique si cela s'avère une bonne ou mauvaise chose.

Autre fonctionnalités C# 8: 

D'autres changements sont prévus, mais je reviendrai dessus lors d'un prochain billet car le sujet est assez conséquent, notamment :

  1. Improved Extension Support : possibilité d'utiliser les methodes d'extensions, notamment sur la notion de properties, méthodes statiques et bien plus.
  2. Async Streams : possibilité d'avoir des énumérations sur le support d'opérations asynchrone notamment avec IAsyncEnumerable<T>
  3. Async Disposable : Ou encore la création de l'interface IAsyncDisposable pour autoriser d'avoir des objets avec une méthode dispose asynchrone.

Bref pas mal de petites choses intéressante à venir :)


Rejoindre la conversation