AlgoWin - James RAVAILLE
http://www.algowin.fr
Langage C# 7
Nouveautés
Spécialiste de la formation et de l’ingénierie avec la plateforme Microsoft .NET
AlgoWin - James RAVAILLE
PRÉSENTATION
Dans ce document, nous vous présentons quelques unes de ces
nouveautés
Programmation
fonctionnelle
Amélioration des
performances
Simplification du code
• Méthodes locales
• Tuples
• Déconstructeurs
• Pattern matching
• Variables locales et retour
de fonctions par référence
• Généralisation des types
de retour asynchrones
• Littéraux binaires
• Séparateur de chiffres
• Variables de sortie
• Membres sous forme
d’expression
• Amélioration de la levée
des exceptions
AlgoWin - James RAVAILLE
LES MÉTHODES LOCALES
Méthodes implémentées au sein de méthodes
Permettent de simplifier l’implémentation de traitements de données
à usage très local :
public void ExecuterMethodeLocale()
{
bool EstPair(int aNombre)
{
// Traitement.
return aNombre % 2 == 0;
}
bool bResult = EstPair(10);
List<int> oListe, oListeNbPairs;
oListe = new List<int>() { 1, 4, 8, 9, 13 };
oListeNbPairs = oListe.Where(i => EstPair(i)).ToList();
}
Utilisation de la méthode locale. La méthode locale EstPair
ne peut être appelée que depuis le code de
ExecuterMethodeLocale
AlgoWin - James RAVAILLE
LES TUPLES (1)
Lors de l’implémentation de fonctions, il est parfois nécessaire de
renvoyer plusieurs informations
Avec la version 4.6.2 du Framework .NET, il est nécessaire d’installer le
package Nuget System.ValueTuple
Méthode retournant un couple d’informations :
Méthode retournant une liste de couples d’informations :
public (int, string) GetFormation()
{
return (100, "Formation C#");
}
public List<(int, string)> GetListeFormations()
{
return new List<(int, string)> {
(100, "Formation Windows Presentation Foundation"),
(150, "Formation .NET Core")};
}
(int, string) oFormation = oNouveaute.GetFormation();
List<(int, string)> oListeFormations = oNouveaute.GetListeFormations();
AlgoWin - James RAVAILLE
LES TUPLES (2)
public (int NbValeurs, long SommeValeurs) GetInfoCollection(IEnumerable<int> aListeValeurs)
{
int iNbValeurs = 0;
long lSommeValeurs = 0;
foreach (int dValeur in aListeValeurs)
{
iNbValeurs++;
lSommeValeurs += dValeur;
}
return (iNbValeurs, lSommeValeurs);
}
Retourne à la fois le nombre et la somme des nombres
(int NbValeurs, long SommeValeurs) oResult = this.GetInfoCollection(oListeNombres);
AlgoWin - James RAVAILLE
LES DÉCONSTRUCTEURS
Permet de « déconstruire » un objet vers un tuple
La classe permettant de créer cet objet doit implémenter une
procédure :
• Nommée Decontruct
• Avoir des paramètres de sortie indiquant les informations à fournir au tuple
public class Heure
{
public int Minutes { get; set; }
public int Secondes { get; set; }
public Heure(int aMinutes, int aSecondes)
{
this.Minutes = aMinutes;
this.Secondes = aSecondes;
}
public void Deconstruct(out int aMinutes, out int aSecondes)
{
aMinutes = this.Minutes;
aSecondes = this.Secondes;
}
}
Cette méthode sera appelée lors de la création du tuple.
Elle peut être surchargée
AlgoWin - James RAVAILLE
LES PATTERNS MATCHINGS
Permet de déterminer si une valeur correspond à des cas prédéfinis.
Exemple :
switch (aFormeGeometrique)
{
case Rectangle oRectangle:
{
sMessage = $"Aire du rectangle : {oRectangle.Largeur * oRectangle.Hauteur}";
break;
}
case Disque oDisque when oDisque.Rayon <= 10:
{
sMessage = "Disque usé";
break;
}
case Disque oDisque:
{
sMessage = "Disque neuf";
break;
}
default:
{
break;
}
}
L’instruction switch permet d’évaluer le type
d’un objet
La clause when permet de préciser une
condition
L’ordre des clauses est important afin de
gérer correctement les conflits. Toujours
spécifier de la plus précise à la plus générale
AlgoWin - James RAVAILLE
LES VARIABLES DE SORTIE
L’utilisation des paramètres de sortie nécessitait de déclarer au
préalable les variables avant d’appeler les méthodes qui en utilisaient.
Exemple :
La version 7 du langage C# permet de déclarer ces variables
directement dans l’appel des méthodes :
string sValeur = "10";
int iValeur;
bool bResult = int.TryParse(sValeur, out iValeur);
bool bResult = int.TryParse(sValeur, out int iValeur);
Déclaration de la variable correspondant au paramètre de sortie
(résultat de la conversion en cas de réussite)
Il est également possible d’ignorer la valeur du paramètre de sortie,
en spécifiant « _ » en lieu et place du nom de la variable
Aussi, l’utilisation de l’inférence de type est autorisée
AlgoWin - James RAVAILLE
MEMBRES SOUS FORME D’EXPRESSION
La version 6 du langage C# a introduit cette fonctionnalité pour les
propriétés (accesseurs), les méthodes et indexeurs
La version 7 l’étend aux constructeurs, destructeurs :
public class Heure
{
public int Minutes { get; set; }
public int Secondes { get; set; }
public long TotalSecondes => this.Minutes * 60 + this.Secondes;
public string ToString() => $"({this.Minutes}, {this.Secondes})";
}
private int _Minutes;
public int Minutes { get => this._Minutes; set => this._Minutes = value; }
public long TotSecondes => this.Minutes * 60 + this.Secondes;
public Heure(int aMinutes) => this.Minutes = aMinutes;
public string ToString() => $"({this.Minutes}, {this.Secondes})";
~Heure() => Debug.WriteLine("Finaliseur");
AlgoWin - James RAVAILLE
AMÉLIORATION DE LA LEVÉE D’EXCEPTIONS
Jusqu’à la version 6 du langage C#, l’instruction throw (permettant de
lever une exception), ne pouvait pas être utilisée dans un contexte où
une expression était attendue
La version 7 du langage C# simplifie l’écrire de ces blocs d’instructions :
throw est une instruction convertible en n’importe quel type. Par
exemple, l’écriture de la validation de valeurs des paramètres d’une
méthode est simplifiée :
// Dans une expression lambda.
Func<int> f = () => throw new Exception();
// Dans une expression conditionnelle.
int x = m == 75 ? 25 : throw new Exception();
public class Disque : FormeGeometrique
{
public double Rayon { get; set; }
public Disque(double aRayon) : base()
{
this.Rayon = (aRayon > 0) ? aRayon : throw new ArgumentException(nameof(aRayon));
}
}
AlgoWin - James RAVAILLE
VARIABLES LOCALES ET RETOURS DE FONCTIONS PAR RÉFÉRENCE (1)
Les applications à haute performance utilisent des types valeurs (telles
que les structures) :
• Meilleure gestion de la mémoire
• Gestion de données contigües dans un tableau
Toutefois, l’utilisation de types valeurs implique de nombreuses copies
de données
Les versions précédentes du langage C# permettent depuis toujours de
passer des paramètres par référence plutôt que par valeur, grâce à
l’utilisation du mot clé ref
La version 7 du langage C# étend ce mécanisme aux variables locales et
aux valeurs de retour des fonctions, évitant ainsi les copies inutiles de
données, améliorant ainsi les performances lors de l’exécution
AlgoWin - James RAVAILLE
VARIABLES LOCALES ET RETOURS DE FONCTIONS PAR RÉFÉRENCE (2)
Implémentation de la structure :
Méthode de recherche d’un élément à partir d’un identifiant unique :
Recherche d’un élément :
public struct Structure
{
public Guid Identifiant { get; set; }
public string Nom { get; set; }
}
public static Structure[] _Elements;
public static ref Structure GetElement(Guid aUid)
{
for (int iIndice = 0; iIndice < _Elements.Length; iIndice++)
{
if (_Elements[iIndice].Identifiant == aUid)
{
return ref _Elements[iIndice];
}
}
throw new Exception("Elément non trouvé");
}
ref Structure item = ref GetElement(Guid.Parse("0ED9432A-8BEB-4076-A630-821DA9BE2A21"));

C# 7 - Nouveautés

  • 1.
    AlgoWin - JamesRAVAILLE http://www.algowin.fr Langage C# 7 Nouveautés Spécialiste de la formation et de l’ingénierie avec la plateforme Microsoft .NET
  • 2.
    AlgoWin - JamesRAVAILLE PRÉSENTATION Dans ce document, nous vous présentons quelques unes de ces nouveautés Programmation fonctionnelle Amélioration des performances Simplification du code • Méthodes locales • Tuples • Déconstructeurs • Pattern matching • Variables locales et retour de fonctions par référence • Généralisation des types de retour asynchrones • Littéraux binaires • Séparateur de chiffres • Variables de sortie • Membres sous forme d’expression • Amélioration de la levée des exceptions
  • 3.
    AlgoWin - JamesRAVAILLE LES MÉTHODES LOCALES Méthodes implémentées au sein de méthodes Permettent de simplifier l’implémentation de traitements de données à usage très local : public void ExecuterMethodeLocale() { bool EstPair(int aNombre) { // Traitement. return aNombre % 2 == 0; } bool bResult = EstPair(10); List<int> oListe, oListeNbPairs; oListe = new List<int>() { 1, 4, 8, 9, 13 }; oListeNbPairs = oListe.Where(i => EstPair(i)).ToList(); } Utilisation de la méthode locale. La méthode locale EstPair ne peut être appelée que depuis le code de ExecuterMethodeLocale
  • 4.
    AlgoWin - JamesRAVAILLE LES TUPLES (1) Lors de l’implémentation de fonctions, il est parfois nécessaire de renvoyer plusieurs informations Avec la version 4.6.2 du Framework .NET, il est nécessaire d’installer le package Nuget System.ValueTuple Méthode retournant un couple d’informations : Méthode retournant une liste de couples d’informations : public (int, string) GetFormation() { return (100, "Formation C#"); } public List<(int, string)> GetListeFormations() { return new List<(int, string)> { (100, "Formation Windows Presentation Foundation"), (150, "Formation .NET Core")}; } (int, string) oFormation = oNouveaute.GetFormation(); List<(int, string)> oListeFormations = oNouveaute.GetListeFormations();
  • 5.
    AlgoWin - JamesRAVAILLE LES TUPLES (2) public (int NbValeurs, long SommeValeurs) GetInfoCollection(IEnumerable<int> aListeValeurs) { int iNbValeurs = 0; long lSommeValeurs = 0; foreach (int dValeur in aListeValeurs) { iNbValeurs++; lSommeValeurs += dValeur; } return (iNbValeurs, lSommeValeurs); } Retourne à la fois le nombre et la somme des nombres (int NbValeurs, long SommeValeurs) oResult = this.GetInfoCollection(oListeNombres);
  • 6.
    AlgoWin - JamesRAVAILLE LES DÉCONSTRUCTEURS Permet de « déconstruire » un objet vers un tuple La classe permettant de créer cet objet doit implémenter une procédure : • Nommée Decontruct • Avoir des paramètres de sortie indiquant les informations à fournir au tuple public class Heure { public int Minutes { get; set; } public int Secondes { get; set; } public Heure(int aMinutes, int aSecondes) { this.Minutes = aMinutes; this.Secondes = aSecondes; } public void Deconstruct(out int aMinutes, out int aSecondes) { aMinutes = this.Minutes; aSecondes = this.Secondes; } } Cette méthode sera appelée lors de la création du tuple. Elle peut être surchargée
  • 7.
    AlgoWin - JamesRAVAILLE LES PATTERNS MATCHINGS Permet de déterminer si une valeur correspond à des cas prédéfinis. Exemple : switch (aFormeGeometrique) { case Rectangle oRectangle: { sMessage = $"Aire du rectangle : {oRectangle.Largeur * oRectangle.Hauteur}"; break; } case Disque oDisque when oDisque.Rayon <= 10: { sMessage = "Disque usé"; break; } case Disque oDisque: { sMessage = "Disque neuf"; break; } default: { break; } } L’instruction switch permet d’évaluer le type d’un objet La clause when permet de préciser une condition L’ordre des clauses est important afin de gérer correctement les conflits. Toujours spécifier de la plus précise à la plus générale
  • 8.
    AlgoWin - JamesRAVAILLE LES VARIABLES DE SORTIE L’utilisation des paramètres de sortie nécessitait de déclarer au préalable les variables avant d’appeler les méthodes qui en utilisaient. Exemple : La version 7 du langage C# permet de déclarer ces variables directement dans l’appel des méthodes : string sValeur = "10"; int iValeur; bool bResult = int.TryParse(sValeur, out iValeur); bool bResult = int.TryParse(sValeur, out int iValeur); Déclaration de la variable correspondant au paramètre de sortie (résultat de la conversion en cas de réussite) Il est également possible d’ignorer la valeur du paramètre de sortie, en spécifiant « _ » en lieu et place du nom de la variable Aussi, l’utilisation de l’inférence de type est autorisée
  • 9.
    AlgoWin - JamesRAVAILLE MEMBRES SOUS FORME D’EXPRESSION La version 6 du langage C# a introduit cette fonctionnalité pour les propriétés (accesseurs), les méthodes et indexeurs La version 7 l’étend aux constructeurs, destructeurs : public class Heure { public int Minutes { get; set; } public int Secondes { get; set; } public long TotalSecondes => this.Minutes * 60 + this.Secondes; public string ToString() => $"({this.Minutes}, {this.Secondes})"; } private int _Minutes; public int Minutes { get => this._Minutes; set => this._Minutes = value; } public long TotSecondes => this.Minutes * 60 + this.Secondes; public Heure(int aMinutes) => this.Minutes = aMinutes; public string ToString() => $"({this.Minutes}, {this.Secondes})"; ~Heure() => Debug.WriteLine("Finaliseur");
  • 10.
    AlgoWin - JamesRAVAILLE AMÉLIORATION DE LA LEVÉE D’EXCEPTIONS Jusqu’à la version 6 du langage C#, l’instruction throw (permettant de lever une exception), ne pouvait pas être utilisée dans un contexte où une expression était attendue La version 7 du langage C# simplifie l’écrire de ces blocs d’instructions : throw est une instruction convertible en n’importe quel type. Par exemple, l’écriture de la validation de valeurs des paramètres d’une méthode est simplifiée : // Dans une expression lambda. Func<int> f = () => throw new Exception(); // Dans une expression conditionnelle. int x = m == 75 ? 25 : throw new Exception(); public class Disque : FormeGeometrique { public double Rayon { get; set; } public Disque(double aRayon) : base() { this.Rayon = (aRayon > 0) ? aRayon : throw new ArgumentException(nameof(aRayon)); } }
  • 11.
    AlgoWin - JamesRAVAILLE VARIABLES LOCALES ET RETOURS DE FONCTIONS PAR RÉFÉRENCE (1) Les applications à haute performance utilisent des types valeurs (telles que les structures) : • Meilleure gestion de la mémoire • Gestion de données contigües dans un tableau Toutefois, l’utilisation de types valeurs implique de nombreuses copies de données Les versions précédentes du langage C# permettent depuis toujours de passer des paramètres par référence plutôt que par valeur, grâce à l’utilisation du mot clé ref La version 7 du langage C# étend ce mécanisme aux variables locales et aux valeurs de retour des fonctions, évitant ainsi les copies inutiles de données, améliorant ainsi les performances lors de l’exécution
  • 12.
    AlgoWin - JamesRAVAILLE VARIABLES LOCALES ET RETOURS DE FONCTIONS PAR RÉFÉRENCE (2) Implémentation de la structure : Méthode de recherche d’un élément à partir d’un identifiant unique : Recherche d’un élément : public struct Structure { public Guid Identifiant { get; set; } public string Nom { get; set; } } public static Structure[] _Elements; public static ref Structure GetElement(Guid aUid) { for (int iIndice = 0; iIndice < _Elements.Length; iIndice++) { if (_Elements[iIndice].Identifiant == aUid) { return ref _Elements[iIndice]; } } throw new Exception("Elément non trouvé"); } ref Structure item = ref GetElement(Guid.Parse("0ED9432A-8BEB-4076-A630-821DA9BE2A21"));