Académique Documents
Professionnel Documents
Culture Documents
0
Version 1.4
James RAVAILLE
http://blogs.dotnet-france.com/jamesr
Sommaire
Les accesseurs simplifis ................................................................................................................. 4 2.1 2.2 Prsentation ............................................................................................................................ 4 Exemple de mise en uvre ..................................................................................................... 4
Les mthodes partielles................................................................................................................... 6 3.1 3.2 Prsentation ............................................................................................................................ 6 Exemple de mise en uvre ..................................................................................................... 7
Les initialiseurs dobjets et de collections ....................................................................................... 9 4.1 4.2 Prsentation ............................................................................................................................ 9 Exemple de mise en uvre ..................................................................................................... 9 Les initialiseurs dobjets .................................................................................................. 9 Les initialiseurs de collections ....................................................................................... 10
4.2.1 4.2.2 5
Linfrence de type et les types anonymes ................................................................................... 11 5.1 5.2 5.3 Prsentation de linfrence de type ...................................................................................... 11 Prsentation des types anonymes ........................................................................................ 11 Exemple de mise en uvre ................................................................................................... 11
Les mthodes dextension ............................................................................................................. 13 6.1 6.2 6.3 Prsentation .......................................................................................................................... 13 Exemple de mise en uvre ................................................................................................... 14 Rgles particulires ............................................................................................................... 15
Les expressions lambda ................................................................................................................. 17 7.1 7.2 7.3 Prsentation .......................................................................................................................... 17 Exemple de mise en uvre ................................................................................................... 17 Utilisation des expressions lambda comme paramtre de mthode ................................... 18
Conclusion ..................................................................................................................................... 19
1 Introduction
1.1 Prsentation
En Fvrier 2008, Microsoft sort officiellement et pour le grand public, Visual Studio 2008, la version 3.5 du Framework .NET, ainsi quune nouvelle version du langage C#. Nous vous proposons dans ce cours, de vous prsenter chacune des nouveauts de ce langage, avec pour chacune dentre elles : Une partie thorique afin de vous expliquer en quoi elle consiste, et quel est son but, dans quels cas il est ncessaire/conseill de lutiliser Une partie pratique avec des exemples de mise en uvre.
Ces nouveauts sont les suivantes : Les accesseurs simplifis. Les mthodes partielles. Les initialiseurs dobjets et de collections. Linfrence de type. Les types anonymes. Les mthodes dextension. Les expressions lambda.
1.2 Pr-requis
Avant de lire ce cours, vous devez avoir lu les prcdents cours sur le langage C# : Le langage C#. La programmation oriente objet avec le langage C#. Les nouveauts du langage C# 2.0.
La classe ci-dessus prsente : Un attribut avec son accesseur (aussi appel accesseur par dfaut ), contenant le numro dimmatriculation dune voiture. Un autre accesseur avec une forme particulire, contenant la marque dune voiture : les accesseurs en lecture et en criture ne sont pas implments. Il sagit dun accesseur simplifi. Au final, lors de la gnration du code MSIL, notre classe possde deux attributs, et pour chacun dentre eux, un accesseur. Pour lobserver, il suffit de rtro-compiler le code Dotnet France Association James RAVAILLE
Les nouveauts du langage C# 3.0 MSIL de cette classe, avec un outil tel que gate.com/products/reflector). Voici ce quon peut observer : Reflector (http://www.red-
public class Voiture { // Fields private string _NumeroImmatriculation; [CompilerGenerated]private string <Marque>k__BackingField; // Properties public string Marque { [CompilerGenerated] get; [CompilerGenerated] set; } public string NumeroImmatriculation { get; set; }
Voici les caractristiques des mthodes partielles : Elles sont obligatoirement prives. Elles ne peuvent tre appeles que dans la classe dans laquelle elles sont dfinies. Aucun niveau de visibilit ne doit tre spcifi (une erreur de compilation survient, le cas chant). Elles sont dfinies avec le mot cl partial.
Lintrt majeur des classes partielles rside dans les gnrateurs de code, ou bien encore dans des projets qui partagent des assemblies communes :
ou
Classe partielle VoitureCourse Fichier VoitureCourse1.cs Classe VoitureCourse Classe partielle VoitureCourse Fichier VoitureCourse2.cs
Par exemple, via un gnrateur de code (prenons par exemple LINQ for SQL), on gnre une classe. Cette classe contient des membres pour lesquels il nest pas possible de dfinir une implmentation lors de la gnration. Le gnrateur de code ne gnre alors que la signature de la mthode, et les appels de cette mthode dans la mme classe. Cette implmentation ne peut tre fournie que par le dveloppeur 2. Ce dernier, au lieu de la fournir dans le fichier gnr (ces Dotnet France Association James RAVAILLE
Les nouveauts du langage C# 3.0 modifications pourraient tre perdues lors dune prochaine gnration de la classe), va la fournir en dfinissant la mme mthode partielle dans une autre partie de la classe partielle.
La mthode Demarrer est une mthode partielle. Cette mthode est appele dans le constructeur de la mme classe. Nous avons vu prcdemment, que limplmentation de la mthode partielle dans lautre classe partielle est optionnelle. Si on observe le code C# rtro-compil de lassembly contenant cette classe avec loutil Reflector (http://www.redgate.com/products/reflector), alors on peut observer que lappel de la mthode Dmarrer, est prsent uniquement si limplmentation est ralise dans une autre partie de la classe partielle. Voici un exemple dimplmentation de la mthode Dmarrer. Cette mthode aussi ne doit pas tre dfinit avec un niveau de visibilit, et doit avoir la mme signature que la mthode prcdemment dfinie :
Les initialiseurs de collection permettent de dfinir quels sont les lments qui constituent cette collection, lors de son instanciation. Ils permettent ainsi de simplifier la cration et lalimentation dune collection de donnes ou dobjets.
// C# partial class VoitureCourse { #region Attributs et accesseurs private string _NumeroImmatriculation; public string NumeroImmatriculation { get { return _NumeroImmatriculation; } set { _NumeroImmatriculation = value; } } public string Marque { get; set; } #endregion #region Constructeurs public VoitureCourse(string aNumeroImmatriculation) { this.NumeroImmatriculation = aNumeroImmatriculation; this.Marque = string.Empty; this.Demarrer(); } public VoitureCourse() : this(string.Empty) { } #endregion #region Methodes partial void Demarrer(); #endregion }
10
Voici un bloc dinstruction C#, permettant de crer une instance de cette classe, en utilisant un constructeur dfini dans la classe, et linitialiseur dobjets :
// C# Voiture oVoiture ; oVoiture = new Voiture() { Marque = "Renault", NumeroImmatriculation = "212 YT 44" };
Via linitialisation dobjet, il est ainsi possible dans la mme instruction, de crer une instance de la classe VoitureCourse en utilisant lun des deux constructeurs prsents dans la classe, et dinitialiser tous les attributs souhaits. A noter que le constructeur est toujours appel avant linitialisation des attributs.
4.2.2
Les initialiseurs de collections Voici un exemple, montrant commun crer une collection de nombre entiers :
Voici un autre exemple, montrant comment crer une collection dobjets de type VoitureCourse :
// C# List<Voiture> oListeVoitures = new List<VoitureCourse>() { new VoitureCourse ("34 YT 54"), new VoitureCourse ("17 RE 33"), new VoitureCourse ("106 IU 75") {Marque="Peugeot"} };
Lexemple ci-dessus, vous montre quil est aussi possible dutiliser linitialisation dobjets, dans une instruction utilisant linitialisation de collections.
11
12
// C# var oVoiture = new { Marque = "Renault", NumeroImmatriculation = "212 YT 44", Couleur = Color.Black };
Il est alors possible de crer des objets, contenant uniquement des donnes, sans avoir implmenter dans le code la classe permettant de les crer. On remarque lutilisation du mot cl var, marquant lutilisation de linfrence de type.
Voici un autre exemple, qui montre lutilisation de linfrence de type, dun type anonyme et linitialisation dobjets. La requte LINQ permet dobtenir une collection dobjets, o chacun contient une marque de voiture et un numro de dpartement, partir dune collection de voitures. Seules les voitures immatricules dans les dpartements 44 et 35, doivent tre slectionnes :
// C# var oListeVoitures1 = (from oVoiture in oListeVoitures where oVoiture.NumeroImmatriculation.EndsWith("44") || oVoiture.NumeroImmatriculation.EndsWith("35") select new { Marque = oVoiture.Marque, Departement = oVoiture.NumeroImmatriculation.Substring(oVoiture.NumeroImmatriculation.L ength - 2) }).ToList();
13
Alors si on tend linterface IVehicule par une mthode dextension, alors cette mthode dextension est applicable toutes les instances, cres partir des classes implmentant cette interface.
Vous dveloppez une application, qui utilise des classes contenues dans un assembly qui vous a t fourni. Vous ne possdez pas les sources de cet assembly. Vous savez quil contient une classe Animal, qui possde des classes drives. Vous souhaitez alors ajouter des membres supplmentaires cette classe, afin denrichir les classes drives. Comme vous ne possdez pas les sources de lassembly, vous ne pouvez le faire autrement quen crant des mthodes dextension, qui tendent la classe Animal.
En C#, une mthode dextension est une mthode statique, contenue dans une classe statique. Cette mthode sera utilise : Comme toute mthode statique, en passant en paramtre lobjet laquelle elle sapplique. Ainsi dans lcriture du code, il est possible dexcuter linstruction suivante sans la leve dune exception de type NullReferenceException, mme si lobjet oVoiture est null ; la mthode Garer sera appele, avec la valeur null en paramtre :
14
// C# oVoiture.Garer();
La signature de cette mthode est particulire : le type du premier paramtre est prfix du mot cl this, et ce type reprsente le type tendu. Une mthode dextension peut possder des paramtres dentre, qui sont alors ajouts la suite de ce premier paramtre.
Elle permet de multiplier par deux le contenu de toute variable de type System.Int32. Voici un exemple :
// C# int i = 10; Console.WriteLine(i.MultiplierParDeux()); => Affiche 10 * 2 = 20
Un autre exemple : toutes les classes reprsentant un dictionnaire de donnes, dit gnrique implmente linterface IDictionary<TKey, TValue> du Framework .NET. Alors voici une mthode permettant dtendre toute collection de donnes, implmentant cette interface, de manire pouvoir accder la valeur dun lment partir de sa cl, ou obtenir une valeur par dfaut, si aucun lment de la collection nest identifi avec la cl :
15
// C# public static class IDictionnaryExtension { public static TValue GetValue<TKey, TValue>( this IDictionary<TKey, TValue> aListe, TKey key, TValue defaultValue) { TValue aValeurRetour; if (aListe.ContainsKey(key)) aValeurRetour = aListe[key]; else aValeurRetour = defaultValue; return aValeurRetour; } }
Et voici un exemple dutilisation de la mthode dextension, avec la classe gnrique Dictionary<TKey, TValue>, qui implmente linterface gnrique IDictionary<TKey, TValue> :
// C# // Cration de la collection de donnes. Dictionary<int, string> oListeFormations = new Dictionary<int, string>(); oListeFormations.Add(1, "Formation C#"); oListeFormations.Add(2, "Formation ASP .NET"); oListeFormations.Add(3, "Atelier Accs aux donnes"); oListeFormations.Add(4, "La scurit dans les applications .NET"); // Utilisation de la mthode dextension. string sFormation = oListeFormations.GetValue(5, "formation inexistante");
Le corps des mthodes dextension peut tre paramtrables , personnalisables , au travers de lutilisation dexpressions lambda.
16
Les nouveauts du langage C# 3.0 Voici quelques rgles observer lors de lutilisation de mthodes dextension : Si les classes IVehiculeExtension et ITransporteurExtension possdent une mthode dextension de mme nom et avec une signature analogue , alors une erreur survient lors de la compilation, lorsque cette mthode est applique une instance de la classe Vehicule. Si la classe Vehicule contient une mthode, et que la classe IVehiculeExtension et/ou ITransporteurExtension propose une mthode dextension de mme nom et avec une signature analogue , alors lapplication compile et la mthode de la classe Vehicule masque les mthodes dextension.
17
Avec le langage C# 3.0, en utilisant la mthode dextension Where de linterface gnrique IEnumerable<T>, on crirait le bloc de code suivant :
// C# List<int> oListeNombres = new List<int>() { 1, 34, 3, 9, 12, 18}; List<int> oListeNombrePaires; oListeNombrePaires = oListeNombres.Where(i => i % 2 == 0).ToList();
Le bloc de code C# ci-dessus utilise la mthode dextension Where, tendant linterface gnrique IEnumarable<T> du Framework .NET. Cette mthode permet de filtrer la collection dentiers, en fonction dune expression boolenne. Cette expression boolenne est dfinie via lexpression lambda i => i % 2 == 0, qui signifie pour tous les nombres i de la collection pour lesquels le rsultat du modulo par deux vaut 0 . Dotnet France Association James RAVAILLE
18
Pour dfinir une expression lambda, il suffit dutiliser le mot cl Func permettant de dfinir des types de donnes (une volution des dlgus). Dans lexemple prcdent, Func<int, int> dcrit une expression de traitement acceptant une donne de type int en paramtre (le premier type prcis), effectuant un traitement avec ou sur ce paramtre, et retournant une donne de type int (second type de donne dfini).
Enfin, voici deux blocs de code utilisant la mthode TraiterElements sur une collection dentiers, afin de multiplier par 2 chacun des nombres de la collection :
// C# // Premier exemple. Func<int, int> oExpressionTraitement = (i) => i * 2; oListeNombres.TraiterElements(oExpressionTraitement); // Second exemple. oListeNombres.TraiterElements((i) => i * 2);
19
8 Conclusion
Ce chapitre vous a prsent les nouveauts du langage C# 3.0. Ces nouveauts ont t ncessaires, afin de permettre dcrire des requtes LINQ (sur une grappe dobjets, sur une base de donnes SQL Server, ou sur un flux XML), et lutilisation de composants daccs aux donnes tels que Classes LINQ For SQL. Voici un exemple, qui rcapitule et combine de nombreuses nouveauts du langage C# 3.0, au travers dune requte LINQ : crire une requte LINQ, permettant de slectionner la liste des fichiers dextension txt dun rpertoire, dont la taille est strictement suprieure 10 Ko. En sortie, on doit obtenir uniquement le nom et la taille des fichiers en octets, dans lordre alphabtique invers sur le nom :
// C# DirectoryInfo oDirInfo = new DirectoryInfo(@"c:\transfert"); // Slection de la liste des fichiers (requte LINQ). var oListeFichiers = oDirInfo.GetFiles("*.txt") .Where(oFichier => oFichier.Length > 10 * 1024) .OrderByDescending(oFichier => oFichier.Name) .Select(oFichier => new { oFichier.Name, Taille = oFichier.Length }); // Affichage de la liste des fichiers. foreach (var oFichier in oListeFichiers) { Console.WriteLine(oFichier.Name + " : " + oFichier.Taille.ToString()); }
La requte LINQ prsente dans le bloc de code ci-dessus, utilise pleinement les nouveauts du langage C# 3.0 que nous avons tudies dans ce support : Infrence de type : lie lutilisation du type anonyme, et marque par lutilisation du mot cl var. Mthodes dextension : marques par lutilisation des mthodes dextension Where, OrderByDescending, et Select de linterface gnrique IEnumerable<T> du Framework .NET. Type anonyme : marque par lutilisation du mot cl new, et la projection de donnes effectue en ne slectionnant que le nom et la taille du fichier en octets. Expressions lambda : utilises dans les trois mthodes dextension. Autrement dit, pour filtrer, trier les fichiers, et raliser une projection de donnes sur les informations des fichiers. Initialisation dobjet : utilise au sein du type anonyme.