Les nouveautés de C# 7

L’objectif de cet article est de présenter aux développeurs les dernières nouveautés de la version 7 de C# en les présentant de manière simple et concise.

Bien entendu, si vous souhaitez avoir plus de détails sur ces nouveautés, je vous invite à vous documenter personnellement pour récupérer les informations qui pourrait vous manquer.

  • La version 7.0

  • Amélioration de la lisibilité du code avec les variables OUT
C# 6 C# 7
string nombreAConvertir = « 7878 »;

int nombre;

if (Int32.TryParse(nombreAConvertir, out nombre))

{

}

string nombreAConvertir = « 7878 »;

if(Int32.TryParse(nombreAConvertir, out int nombre))

{

}

Avec la version 7,  la variable OUT est déclaré au moment où on souhaite l’utiliser, nous ne sommes plus obligés de déclarer préalablement la variable.

  • Amélioration de l’utilisation des tuples
Avant C# 7
Un tuple peut être défini de la façon ci-dessous

Tuple<int, string> tuple = new Tuple<int, string, bool>(1, « pomme »);

Pour accéder aux propriétés du tuples, on le fait simplement avec les propriétés item1, item2… suivant le nombre de propriétés défini dans le tuple.

if (tuple.Item1 == 1) {

Console.WriteLine(tuple.Item1);

}

if (tuple.Item2 == « pomme »){

Console.WriteLine(tuple.Item2);

}

Depuis C# 7
Il est bien entendu toujours possible de déclarer les tuples comme indiqué ci-dessus.

Cependant, d’autres façons de le faire sont maintenant disponible depuis la version 7 de C#.

  • var monTuple = (« test », « test1 »);

monTuple est bien un objet de type Tuple et pour accéder aux valeurs de ce tuple (test et test1), on appellera les propriétés item1 et item2.

  •   (string a, string b) monTuple = (« test », « test1 »);

monTuple est bien un objet de type Tuple et pour accéder aux valeurs de ce tuple(test et test1), on appellera les propriétés a et b.

  •   var monTuple = (a: « test », b: « test1 »);

monTuple est bien une instance d’ objet de type Tuple et pour accéder aux valeurs de ce tuple(test et test1), on appellera les propriétés a et b.

  • Apparition des éléments ignorés avec C# 7
Les éléments ignorés sont des variables temporaires factices utilisées dans le code,

  • n’ayant aucune valeur.
  • défini juste par un underscore (_).

 

Utilisé dans le cadre de la déconstruction d’un tuple
var (_, _, _, a, _, b) = ReturnTuple();

ReturnTuple est une méthode qui retourne un tuple de six éléments.

De tous ces élements retournés, certaines valeurs peuvent être inutilisés car , pas nécessaire. Les éléments ignorés indiqués ci-dessus permettent ainsi de réduire les allocations de mémoire : la methode retourne bien les valeurs du tuple mais du fait que certaines valeurs ne nous intéresse pas, on définit alors des élements ignorés.

  • Apparition du pattern matching avec C# 7
Avant C# 7
  • Le mot-clé is vérifie si un objet est compatible avec un type donné

Exemple : expr is Type

  • Le mot-clé switch est une instruction de sélection qui teste la valeur d’une constante.

Exemple : switch (expr)

case constant:

Après C# 7
  • Le mot-clé is prend en charge en plus
  • Le modèle de type : expr is Type nomVariable
    • is vérifie si expr peut être convertie avec le type Type, et si cela est possible effectue le cast directement.

Exemple : if (o is Employee e)

{return (e.Name);

  • Le modèle de variable : expr is var varName
    • Is vérifie si expr peut être assigné dans la variable varName, et si cela est possible effectue l’assignation directement.

Exemple : if (item is var obj){}

  • Le mot-clé switch prend en charge en plus
    • Tout expression de correspondance non null (IEnumerable, ICollection, Array, Int…).
    • L’apparition de la clause when sur la même ligne d’un case.

Exemple : case Shape shape when shape == null:

  • Apparition des fonctions locales avec C# 7

Une fonction locale est une méthode définie à l’intérieur d’une autre méthode. Cette fonctionnalité a été créé dans le but d’avoir plus de facilité de compréhension dans la lecture du code.

Exemple de fonction locale
private static string GetText(string path, string filename)

{

var sr = File.OpenText(AppendPathSeparator(path) + filename);

var text = sr.ReadToEnd();

return text;

// Ci-dessous, vous trouverez la fonction locale

string AppendPathSeparator(string filepath)

{

if (! filepath.EndsWith(@ »\ »))

filepath += @ »\ »;

return filepath;

}

}

  • Généralisation des expressions-bodied dans C# 7

Les expressions-bodied sont apparus dans la version 6 de C#. En C# 7, elles ont été généralisées au niveau des constructeurs et ses accesseurs.

Exemple d’expression-bodied en C# 7
// Accesseurs

public string Label

{

get => label;

set => this.label = value ?? « Default label »;

}

// Constructeur

public ExpressionMembersExample(string label) => this.Label = label;

  • Valeurs de retour de référence et variables locales de référence en C# 7
Variables de retour de référence
Une valeur de retour de référence permet à une méthode de retourner à un appelant une référence à une variable, plutôt qu’à une valeur.

Exemple :

public ref Person GetContactInformation(string fname, string lname)

{

return ref p;

}

On peut s’apercevoir que la méthode retourne une référence à un objet Person nommé p.

Variables locales de référence
Une variable locale de référence est une variable qui va recevoir une affectation de données ( généralement une méthode) non par par valeur mais par référence.

Exemple :

Person p = contacts.GetContactInformation(« Scott », « Hanselman »);

Ci-dessus, nous avons faire face à une variable locale : la valeur de p est copié à partir de la méthode GetContactInformation, si on modifie p par la suite, la valeur renvoyé par GetContactInformation ne sera pas impactée.

Ref Person p = contacts.GetContactInformation(« Scott », « Hanselman »);

Ci-dessus, nous avons faire face à une variable locale de référence : la valeur de p est désormais un alias de la valeur retournée par GetContactInformation, si on modifie p par la suite, la valeur renvoyée par GetContactInformation sera impactée.

  • Types de retours async généralisés
Nouveautés de C# 7
Au niveau asynchronisme, je ne m’étendrais pas dans cet article sur les mot-clés async et await. Je précise juste que les types de retour retournés dans le cadre d’utilisation de ces mots clés peuvent être Task,Task<TResult> ou void. Pour simplifier tout cela, C#7 permet d’utiliser maintenant un type globale, utilisable dés qu’une méthode est awaitable.

System.Threading.Tasks.ValueTask<TResult>

using System;

using System.Threading.Tasks;

class Program

{

static Random rnd;

static void Main()

{

Console.WriteLine($ »You rolled {GetDiceRoll().Result} »);

}

private static async ValueTask<int> GetDiceRoll()

{

int roll1 = await Roll();

int roll2 = await Roll();

return roll1 + roll2;

}

private static async ValueTask<int> Roll()

{

if (rnd == null)

rnd = new Random();

await Task.Delay(500);

int diceRoll = rnd.Next(1, 7);

return diceRoll;

}

}

  • Amélioration de la syntaxe litérale numérique
Nouveautés de C# 7
Avec C# 7, il est possible désormais d’utiliser  des séparateurs de chiffres pour une meilleure compréhension du code dans la lecture de constantes numériques.

public const int SixtyFour = 0b0100_0000;

public const long BillionsAndBillions = 100_000_000_000;

public const double AvogadroConstant = 6.022_140_857_747_474e23;

public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720 ;


  • La version 7.1

  • Expressions littérales par défaut
Nouveautés de C# 7
Dans l’optique de toujours plus simplifier le code, le mot-clé default pourra être utilisé de manière littérale pour initialiser des variables, des paramètres de méthodes où bien des instructions de retour.

Cela initialise la chaine à la valeur par défaut d’une string, à savoir null.

string maChaine=default ;

L’utilisation du mot clé dans un paramètre de méthode.

public LabeledPoint(double x, double y, string label = default)

{

X = x;

Y = y;

Label = label;

}

L’utilisation du mot clé en retour d’une méthode.

public static LabeledPoint MovePoint(LabeledPoint source,

double xDistance, double yDistance)

{

// return a default value:

if (source == null)

return default;

return new LabeledPoint(source.X + xDistance, source.Y + yDistance,

source.Label);

}

  • Async dans main
Le mot-clé async pourra être utilisé dans une méthode main.
  • Simplification de fonctionnalité de tuple
  • var monTuple = (a: « test », b: « test1 »);

monTuple est bien un objet de type Tuple et pour accéder aux valeurs de ce tuple(test et test1), on appellera les propriétés a et b.

Cependant en version C# 7.1, la définition du tuple  peut être redéfini de la façon suivante, toujours pour des raisons de simplification de code.

string a= « test »,

string b= »test1″,

  • var monTuple = (a, b);

  • La version 7.2

  • Apparition de private protected
  • Private protected :  cela veut dire qu’un membre pourra être accessible depuis les classes dérivés du même assembly de la classe principale
  • Arguments nommés non placés à la position de fin
Depuis C#4 sont apparus les arguments nommés (exemple ci-dessous)

PrintOrderDetails(orderNum: 31, productName: « Red Mug », sellerName: « Gift Shop »);

Les arguments nommés améliorent la lisibilité du code en identifiant ce que chaque argument représente.

Il ne faut pas les confondre avec des arguments de position (exemple ci-dessous)

PrintOrderDetails(orderNum, productName, sellerName);

 

Depuis la version C# 7.2, nous avons la possibilité de mixer les deux types d’arguments dans l’appel de la méthode.

PrintOrderDetails(orderNum :31, « Red Mug » , sellerName: « Gift Shop » );


  • La version 7.3

  • Prise en charge des opérateurs d’égalité et d’inégalité avec les tuples
Depuis la version 7.3, nous avons la possibilité dorénavant d’utiliser les opérateurs d’égalité == et d’inégalité. Le mode de fonctionnement est basique, il compare chaque membre de l’argument de gauche à chaque membre de l’argument de droite.
Exemple :
var test= (a: 5, b: 10);
var test1= (a: 5, b: 10);
Console.WriteLine(test== test1); // Le résultat sera True
  • Réaffectation des variables locales Ref
Il est désormais maintenant possible de pouvoir réaffecter une variable local Ref , qui était déjà un pointeur vers une autre variable.
Exemple :
ref VeryLargeStruct refLocal = ref veryLargeStruct;
refLocal = ref anotherVeryLargeStruct;On voit bien ci-dessus que la variable qui était un pointeur vers l’objet veryLargeStruct sur la première ligne, est désormais un nouveau pointeur vers l’objet anotherVeryLargeStruct sur la deuxième ligne.
  • Amélioration des tableaux stackalloc
Le mot-clé stackalloc est utilisé dans un contexte de code unsafe pour allouer un bloc de mémoire sur la pile. Avec la version 7.3, ce mot-clé peut dorénavant être utilisé avec des tableaux

Avant 7.3
var arr = new int[3] {1, 2, 3};
var arr2 = new int[] {1, 2, 3};
Depuis 7.3
int* pArr = stackalloc int[3] {1, 2, 3};
int* pArr2 = stackalloc int[] {1, 2, 3};
Span<int>arr = stackalloc [] {1, 2, 3};

  • D’autres types pour l’instruction fixed
L’instruction fixed définit un pointeur un pointeur vers une variable managée et épingle cette variable pendant l’exécution de l’instruction.

À compter de C# 7.3, l’instruction fixed s’applique à d’autres types au-delà des tableaux, chaînes, mémoires tampons de taille fixe ou variables non managées.

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.