Patrice Lamarche
Les fonctionnalités du langage C# 3 compatibles avec .net 2.0
Comment utiliser les fonctionnalités du langage C# 3 pour vos applications .net 2.0
Par Patrice Lamarche publié le 23/02/2010 à 21:08, lu 2403 fois, 6 pages
 3 | Nouveautés « basiques »
Pour initialiser un objet en définissant les valeurs des différentes propriétés nous sommes obligés d’ajouter des constructeurs supplémentaires :

public Employee(string firstName, string lastName, int age, string company)

    {

        FirstName = firstName;

        LastName = lastName;

        Age = age;

        Company = company;

    }

Le problème est que si vous souhaitez permettre aux développeurs d’initialiser vos objets de différentes manières vous devez ajouter différentes surcharges au constructeur, ce qui peut compliquer rapidement l’utilisation de la classe. Rien n’est plus embêtant que de se retrouver avec une classe avec une dizaine de constructeurs.
C# 3 résout le problème en proposant une syntaxe d’initialisation d’objets. Nul besoin de définir différents constructeurs, nous avons à présent la possibilité d’initialiser un objet en définissant les valeurs des propriétés que l’on souhaite grâce à la syntaxe suivante :

Employee employee = new Employee() { LastName = "Lamarche", FirstName = "Patrice" };

A noter que nous avons la possibilité d’effectuer le même genre d’opération avec des collections :

List<Employee> employees = new List<Employee>()

                                      {

                                          new Employee(){LastName="Lamarche"},

                                          new Employee(){LastName="Laut"}

                                      };

La création de propriétés se fait habituellement en définissant à chaque fois un getter et un setter qui effectuent les mêmes opérations : retourner et définir la valeur d’un champ privé.
Au lieu de forcer le développeur à répéter cette tâche, C# 3 propose une syntaxe simplifiée qui permet d’éviter la gestion de ce champ privé :

class Employee

{

    public Employee()

    { }

 

    public string FirstName { get; set; }

 

    public string LastName { get; set; }

 

    public int Age { get; set; }

 

    public string Company { get; set; }

}

La classe Employee devient ainsi beaucoup plus claire et moins « verbeuse ».
L’inférence de type permet de déclarer ou utiliser un type sans spécifier explicitement son type. Un exemple de code permet de comprendre rapidement l’intérêt :

var employees = new List<Employee>()

                                           {

                                               new Employee(){LastName="Lamarche"},

                                               new Employee(){LastName="Laut"}

                                           };

 

            foreach (var employee in employees)

            {

                Console.WriteLine(employee.LastName);

            }

Le mot clé var utilisé permet d’indiquer au compilateur de se débrouiller tout seul et de déduire lui-même le type utilisé. Dans notre exemple, la variable employees est bien de type List<Employee> et la variable employee est de type Employee mais au lieu de spécifier nous-même le type de manière explicite, nous laissons le compilateur le déduire seul.
Outre une simplicité au niveau de l’écriture, l’inférence de type est indispensable afin de pouvoir utiliser les types anonymes.

foreach (var employee in employees)

            {

                var fullEmployee =

                    new

                    {

                        LastName = employee.LastName,

                        employee.FirstName,

                        FullName = employee.LastName + " " + employee.FirstName

                    };

            }

Les méthodes d’extensions sont apparues avec C# 3 et permettent d’étendre n’importe quel type, que vous l’ayez créé vous-même ou qu’il soit directement présent dans le framework. Il est tout à fait possible de les utiliser dans votre code .net 2.0 puisqu’il s’agit d’un simple mécanisme implémenté au niveau du compilateur.
Pour créer une méthode d’extension, il faut créer une méthode statique placée dans une classe statique et définir le premier argument avec le mot clé this afin d’indiquer le type que l’on souhaite étendre.

public static class ExtensionMethods

{

 

    public static string FirstLetterInUpperCase(this string word)

    {

        return  word.Substring(0, 1).ToUpper() + word.Substring(1);

    }

}

On appelle ensuite cette méthode d’extension comme s’il s’agissait d’une méthode d’instance :

static void Main(string[] args)

      {

          string word = "bonjour";

          Console.WriteLine(word.FirstLetterInUpperCase());

      }

Pour être capable de créer ce type de méthode, il va falloir utiliser une petite astuce car si vous essayez de saisir le code ci-dessus dans une application basée sur le framework .net 2.0 vous allez avoir droit à un petit message amical du compilateur :
« Cannot define a new extension method because the compiler required type ‘System.Runtime.CompilerServices.ExtensionAttribute cannot be found. Are you missing a reference to System.Core.Dll ?”
Celui se plaint car il n’arrive pas à trouver un attribut particulier présent dans l’assembly System.Core.Dll qui est un assembly non disponible dans le framework .net 2 (uniquement en 3.5). La solution pour résoudre ce problème est simple, nous allons nous-même implémenter la classe ExtensionAttribute afin d’aider le compilateur à faire son travail. Pour cela, il faut ajouter une classe dans votre solution en prenant bien attention à utiliser le namespace System.Runtime.CompilerServices :

namespace System.Runtime.CompilerServices

{

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class| AttributeTargets.Assembly)]

    public sealed class ExtensionAttribute : Attribute

    {

    }

}

Le compilateur retrouve ainsi ses petits et vous permet d’implémenter des méthodes d’extension sans aucun problème.
Toutes ces fonctionnalités du langage C# 3 sont disponibles pour vos applications .net 2 voyons maintenant comment aller un peu plus loin.
 
» Démarrer une discussion
 
Discussion démarée par Sébastien Lebreton le 24/02/2010 à 12:00, 1 commentaire(s).