Le sucre syntaxique du C# 3.0

Le C# 3.0 a apporté son lot de nouveautés en terme de compilation, permettant des simplifications d'écriture sans aucune incidence sur la nature du code compilé.
En voici une petite présentation rapide.
Vu 2328  fois

 

Les nouveautés présentées ici ne sont que du "sucre syntaxique".
Il s'agit de libertés d'écriture, qui n'apportent aucune nouvelle fonctionnalité, mais simplifient la vie du développeur.
Le compilateur se charge ensuite d'effectuer lui-même les transformations (souvent laborieuses et répétitives).

 

Simplification du couple variable privée / accesseur

La définition d'un accesseur sans préciser le contenu des get/set suffit au compilateur pour créer lui-même la variable privée associée.

 

public class Bonhomme
{
   internal string Nom
   {
      get;
      set;
   }
   internal string Prenom
   {
      get;
      set;
   }
   internal int Age
   {
      get;
      set;
   }
}

 

Une fois compilée, il n'y a plus de différence avec une définition classique.

 

Déclaration implicite de constructeurs

 

Avec la déclaration de la classe ci-dessus, il va être possible d'utiliser des constructeurs utilisant n'importe quelle combinaison de champs.

 

Bonhomme patrick = new Bonhomme { Prenom = ´Patrick´, Nom = ´AVENEL´ };
Bonhomme aleks = new Bonhomme { Prenom = ´Aleks´ };
Bonhomme nouveauNe = new Bonhomme { Age = 0 };
 
 

 

Il est à noter que le comportement sera bien celui d'un constructeur, la variable patrick n'étant à aucun instant valorisé avec un objet Bonhomme dont les propriétés ne seraient pas renseignées.
Pour ce faire, le compilateur crée un objet Bonhomme dans une variable locale spécifique, puis renseigne les propriétés, avant de l'affecter.

 

Le typage automatique

 

Lorsque le type de la variable peut-être deviné par le compilateur, il n'est plus nécessaire de le définir explicitement.
Il s'agit néanmoins d'un typage fort, et on dispose bien de l'Intellisense dans Visual Studio et d'un contrôle à la compilation.

 

var patrick = new Bonhomme { Nom = ´AVENEL´, Prenom = ´Patrick´ };
var nom = patrick.Nom;
var contenu = nom.ToCharArray()

 

On constate néanmoins que cette simplification peut nuire à la lisibilité et devra être utilisée avec parcimonie.

 

Extension de classe

 

Une autre possibilité offerte par le C# 3.0 est d'ajouter des méthodes à une classe existante !

 

public class ExtensionDeClasse 
{
   public static string RecupererNomComplet(this Bonhomme bonhomme)
   {
      return string.Format("{0} {1}", bonhomme.Prenom, bonhomme.Nom);
   }
}

 

On a ainsi étendu la classe Bonhomme pour lui ajouter une méthode permettant de récupérer le nom complet sans modifier l'implémentation de la classe.

 

var patrick = new Bonhomme { Prenom = ´Patrick´, Nom = ´AVENEL´ };
var nomComplet = patrick.RecupererNomComplet();

 

Le compilateur va en fait interpréter (avant optimisation eventuelle) :

 

Bonhomme temp = new Bonhomme();
temp.Prenom = ´Patrick´;
temp.Nom = ´AVENEL´;
Bonhomme patrick = temp;
string nomComplet = ExtensionDeClasse.RecupererNomComplet(patrick);

 

Remplissage simplifié de listes

 

Sur le même principe que la simplification des constructeurs, l'initialisation d'une liste dynamique est simplifiée.

 

var gens = new List<Bonhomme> {
   new Bonhomme { Prenom = ´Patrick´, Nom = ´AVENEL´ },
   new Bonhomme { Prenom = ´Aleks´ },
   new Bonhomme { Age = 0 }
}

 

De même que dans les exemples précédents, le compilateur va en fait compiler cette instruction comme nous l'aurions écrite en 2.0, à l'aide de Add(...) successifs.

 

Exemple d'application

 

En se basant sur les exemples précédents, il est possible d'écrire le code suivant :

 

foreach (var personne in gens) 
{
   Console.WriteLine(personne.RecupererNomComplet());
}

 

Il est à noter que c'est là que le var prend son sens, à savoir qu'il ne sera pas nécessaire de modifier ce code même si le type de la variable gens devait changer.
La seule contrainte est qu'il s'agisse toujours d'une liste de variables exposant une méthode RecupererNomComplet(). Le compilateur se chargera bien sur de cette vérification.

 

Les dangers de l'extension de méthode

 

Il est bon de noter que l'extension de méthode présente quelques risques puisqu'elle conduit à des conflits dans certains cas de figure.
Admettons que la classe Danger implémentant IDanger soit fournie par une DLL externe à notre projet.

 

Il nous est tout à fait possible de définir les extensions suivantes :

 

public class MesExtension
{
   public static int Niveau(this Danger danger)
   {
      return 3;
   }
   public static int Niveau(this IDanger danger)
   {
      return 2;
   }
}

 

La valeur retournée par la méthode Niveau() appelée sur un même objet dépendra de son "cast" courant.

 

Danger monDanger = new Danger();
int niveau1 = monDanger.Niveau(); // niveau1 vaudra 3
int niveau2 = (IDanger)monDanger.Niveau(); // niveau2 vaudra 2

 

En soi, cela représente déjà un risque non négligeable. Mais il y a pire.
Si demain une montée de version sur notre DLL externe amène la classe Danger à implémenter nativement une méthode Niveau(), c'est celle-ci qui sera désormais utilisée, sans que l'on n'en soit jamais averti par le compilateur !

 

Conclusion

 

Si certains aspects vont nous simplifier la vie, le var et les extensions de méthodes sont à utiliser avec parcimonie !
Le sucre syntaxique n'est évidemment pas la seule nouveauté du C# 3.0, et sans doute pas la principale, mais les autres nouveautés feront l'objet d'un autre article.


 

Publié le  14/02/2008
Auteur:  Patrick A

 

Commentaires

Posté le : 15/02/2008 Par : Aleks

Merci pour cet article Patrick.
Ca fait un moment que je n'arrive pas à me tenir au courant des nouveautés et grace à toi je rattrape un peu mon retard :)

Si vous souhaitez ajouter un commentaire vous devez être authentifié.

 

ASP MAGAZINE  ASP-PHP.NET  C²I  CodePPC  CodeS-SourceS  Dotnet-News.com  Tech Head Brothers 

Dotnet-Project.com© tous droits réservés
Webmaster Aleks. Ont collaboré à l'aboutissement de ce projet :
CodeS-SourceS.com, ASP-PHP.Net, DotNet-FR.org, C2i.fr, Newsletter ASP.NET.