Sortie avec Visual Studio 2017, C# 7 est l’une des dernières version largement étendue de C#. C# 8 cible spécifiquement .NET Core et C# 9 n’est disponible qu’à partir de la version .NET 5. C#10 n’est prit en charge qu’à partir de .NET 6.
Fonctions locales
Comme son nom l’indique, cette fonctionnalité permet de déclarer des méthodes à l’intérieur d’autres méthodes : simplement la portée est local à la méthode dans laquelle elle est déclarée. Un avantage est qu’elle peut exploité directement des paramètre de la méthode conteneur.
Monster GetClosestTarget(Point playerPosition, Monster[] monsters)
{
double GetDistance(Point p)
{
double dx = playerPosition.X - p.X;
double dy = playerPosition.Y - p.Y;
return Math.Sqrt(dx * dx + dy * dy);
}
return monsters
.OrderBy(m => GetDistance(m.Position))
.FirstOrDefault();
}
Tuple
La documentation Microsoft indique :
La fonctionnalité tuples fournit une syntaxe concise pour regrouper plusieurs éléments de données dans une structure de données légère
Types Tuple (référence C#)
Un Tuple est donc un type de donnée regroupant plusieurs éléments de données (string, int, etc.).
(string, int) monTuple = ("Ok",1);
Console.WriteLine($"Tuple stocké dans monTuple avec les éléments {monTuple.Item1} et {monTuple.Item2}.");
(string text, int number) monTupleNomme = ("Ok",1);
var monTupleNomme = (myText:"Ok",myNumber:1);
Console.WriteLine($"Tuple stocké dans monTuple avec les éléments {monTuple.text} et {monTuple.number}.");
var (myText, myNumber) = ("ok",1); //Tuple déconstructé dans deux variable
Console.WriteLine($"monTuple a été récupéré dans myText : {myText} et myNumber : {myNumber}.");
Ainsi, une méthode peut elle-même renvoyer un tuple
(int min, int max) GetMinAndMax(int[] input)
{
var min = int.MaxValue;
var max = int.MinValue;
return (min,max);
}
Déconstructeur
Comme vu avec les Tuple, il est désormais possible de déconstruire un objet. Cela passe par la méthode « Deconstruct » et des paramètres de sortie.
public void Deconstruct(out double x, out double y)
{
x = this.X;
y = this.Y;
}
L’objet instancié dont la classe intègre ce « descontructeur » pourra retourner un un tuple de donnée choisis :
(int x, int y) tuplePoint = p; //p étant une instance de la classe Point(int x, int y);
Pattern Matching
Le pattern matching intègre une comparaison plus fine permettant de plus facilement réaliser des conditions selon les types.
//Pour une classe Kid qui dérive de People (ayant Age et Name)
People people = new Kid(12, "brian"); //Kid dérivant de People
if(people is Kid k){
Console.WriteLine(&"You're too young {k.Name}");
}
else if(people is Adult a && a.Age < 50){
Console.WriteLine("Welcome {a.name}");
}
else {
Console.WriteLine("You're too old Dude");
}
Création à la volée de Out
Il est dorénavant possible de créer à la volée des variable sans les déclarer au préable : ici la variable out est déclarée dans le TryParse :
if (int.TryParse(s, out int i))
{
Console.WriteLine($"La chaine représente un entier de valeur {i}");
}
Les Abandons
De plus il est aussi possible d’ignorer des variables si on n’en a pas besoin avec le caractère _
Dans l’exemple précédent, cela donnerait :
if (int.TryParse(s, out _))
{
Console.WriteLine("La chaine représente un entier");
}
Les variable ainsi déclarée sont équivalent à des variables non attribuées :
Les abandons sont équivalents à des variables non attribuées ; ils n’ont pas de valeur. Un abandon communique l’intention au compilateur et à d’autres personnes qui lisent votre code : vous avez prévu d’ignorer le résultat d’une expression.
Ignorer – Principes fondamentaux de C#
Cela peut s’appliquer aussi par exemple pour une expression lamda ou éncore un Tuple :
var (_, _, area) = city.GetCityInformation(cityName); //Les deux première informations renvoyé par le Tuple seront ignorées
Méthode d’une seule expression pour tous
Depuis C#6 on peut écrire cela pour une methode RevertNumber(int i) :
public int RevertNumber(int i) => i*-1;
//équivalent à :
public int RevertNumber(int i){
return (i*-1);
}
Maintenant cela est aussi possible avec les constructeurs, propriété et finaliseurs.
public Person(string name) => _name = name;
A cela s’ajoute la possibilité de Throw une exception dans de nouveaux cas (dont dans une condition ternaire), une nouveau Type ValueTask pour les methodes asynchrones et des retour de fonctions par référence.
Sources
- https://learn.microsoft.com/fr-fr/dotnet/csharp/whats-new/csharp-version-history
- https://tlevesque.developpez.com/tutoriels/csharp/les-nouveautes-de-csharp-7/#L11
- https://learn.microsoft.com/fr-fr/dotnet/csharp/language-reference/builtin-types/value-tuples
- Ignorer : variables ignorées non attribuées | Microsoft Learn