TP d'applications

1) Les types delegate

Créer un nouveau projet console C#, remplacer le code de la classe générée par :

using System;
using System.Collections.Generic;
using System.Text;

namespace exoDelegate
{

/*      partie à coller*/
         class Calcul
         {
                      public static int somme(int a, int b)
                      {
                            return a + b;
                       }
                       public static int produit(int a, int b)
                       {
                            return a * b;
                        }
           }
          class Program
          {
                        static void Main(string[] args)
                        {
                            int result=0;
                            Console.WriteLine("premier nb svp :");
                            int n1 = Convert.ToInt32(Console.ReadLine());
                            Console.WriteLine("deuxième nb svp :");
                            int n2 = Convert.ToInt32(Console.ReadLine());
                            Console.WriteLine("quelle opération '+' ou '*' :");
                            char choix = (char)Console.Read();
                             switch (choix)
                            {
                                    case '+':
                                         { result = Calcul.somme(n1, n2); break; }
                                    case '*':
                                          { result = Calcul.produit(n1, n2); break; }
                             }
                             Console.WriteLine("resultat :"+result.ToString());
             }
/* fin partie à coller*/

Travail à faire
Sans modifier la classe Calcul, mettre en oeuvre un delegate pour effectuer le même traitement.

2) Type générique et itérateur

Travail à faire
Ecrire une classe générique Pile permettant d'itérer à partir du dernier élément inséré.

Le code :
static void Main(string[] args)
{
           Pile<Personne> p = new Pile<Personne>(4);
           p.depile();
           p.empile(new Personne("toto",12));
           p.empile(new Personne("titi",15));
           p.empile(new Personne("tutu",25));
           p.depile();
           p.empile(new Personne("toutou", 28));
           p.empile(new Personne("tintin", 14));
           p.empile(new Personne("tata", 11));
           foreach (Personne pe in p)
                    Console.WriteLine(pe.ToString());
}

doit produire :

On vous donne le code de la classe Personne :

class Personne
{
          public Personne(string nom, int age)
         {this.nom = nom; this.age=age;}
          public override string ToString()
         {
                      return this.nom + " " + this.age.ToString() ;
          }
          private string nom;
          private int age;
}

ainsi que celui de la pile générique :

class Pile<T>
{
         public Pile(int n)
        {
              this.mesT = new T[n];
              this.nbElements = 0;
          }
          public void depile()
         {
                if (this.nbElements > 0)
               this.nbElements--;
          }
          private bool estPLeine()
         {
                  return this.mesT.Length == this.nbElements;
           }
           public void empile(T unT)
          {
                    if (!this.estPLeine())
                    {
                          this.mesT[this.nbElements] = unT;
                          this.nbElements++;
                     }
             }
            public T leT(int n)
             {
                    return this.mesT[n];
               }
              private T[] mesT;
              private int nbElements;
}

Evolution.
Ajouter un événement à la classe Pile qui est généré lorsque la pile est pleine, après l'ajout d'un élément. Prévoir un gestionnaire par défaut qui s'éxécutera automatiquement. Ainsi la sortie suivante :

Il y a eu deux réalisations de l'événement : aux insertions de "Tintin" et "Tata" la première ligne (nombre d'éléments : 4) correspond au gestionnaire par défaut de la classe Pile et le second ("attention pile pleine") correspond à un gestionnaire ajouté.

Pour cela créer un delegate (portée namespace) sans argument et ne retournant rien. Déclarer une fonction déléguée dans la classe Pile ; créér le gestionnaire d'événement par défaut dans la classe Pile, ajouter-le à la fonction déléguée, appeler la fonction déléguée au moment désiré (sur l'ajout quand la pile est pleine). Créer un autre gestionnaire d'événement dans le programme que vous ajoutez à l'événement de l'instance de la pile dans le main. C'est tout :-)

Méthode d'extension

Travail à faire
Ecrire une méthode d'extension retireCar de la classe string qui permet de retirer un caractère d'une chaîne :
string s = "voiture";
  Console.WriteLine( s.retireCar('t'));

affiche voiure


3) Les expressions Lambda

3.1 ) Il serait intéressant de proposer le filtre comme méthode d'extension de l' ArrayList.

Travail à faire
En s'inspirant du code présent dans le support, modifier afin de pouvoir écrire dans le Main :

          ArrayList desInts = new ArrayList();
          for (int i = 1; i <= 100; i++) { desInts.Add(i); } // construction des valeurs

         affiche(desInts.filtre((a) => a % 7 == 0)); // filtre devient une méthode d'extension de l'ArrayList

3.2 ) Filtrons les capitales

Travail à faire
A partir d'une ArrayList initialisée dans le Main :
          ArrayList capitales = new ArrayList() {"Paris","Madrid","Londres","Rome","Genève","Dublin","Moscou","Zurich","Prague" };

En s'inspirant du code précédemment vu, écrire un filtre qui permet d'obtenir (par exemple) les capitales qui commence par "P", ou "Ma", ou se termine par "e" ou "ve" ou contiennent "dr" ou pas de "o" ...
Le filtre ne sera pas une méthode d'extension.

3.3 ) Filtre générique

Lors des derniers tp, un filtre est utilisé, une fois pour des int ou autre fois pour des string ; il serait interessant de proposer une seul filtre générique.

Travail à faire

Ecrire cette nouvelle fonction filtrer générique ; proposer une version sans méthode d'extension et une avec une méthode d'extension de l'ArrayList.

LINQ

En copiant le code :


List<Personne> personnes = new List<Personne>{new Personne("Dupond",15), new Personne("Durand",25),new Personne("Rami",18),
new Personne("Paton",24),new Personne("Harvis",11),new Personne("Breton",32),new Personne("Perdrix",19),
new Personne("Rapport",19),new Personne("Boissette",28),new Personne("Pamelle",45),new Personne("Fétard",15)};

Travail à faire

Ecrire les requêtes Linq qui affichent :

a) Le nom des personnes dont le nom contient ""to"

b) L'age moyen

c) Le nom et l'age de la (ou des) personne(e) la plus agée

d) Le nom et l'age de la (ou des) personne(s) dont le nom est le plus court

4) Entity Framework

4.1 Application Console

Travail à faire
Faire les modifications sur la classe Vehicule (modification de l'id) et sur la classe Lecon (ajout de constructeurs)
Tester en ajoutant une leçon en utilisant Linq (en lieu et place des expressions Lambda)

Lorsqu'une leçon est effectuée, son champ effectueO/N passe à TRUE et le crédit horaire de l'élève est décrémenté en conséquence. Ecrire une méthode setEffectuee() qui effectue ce traitement. Tester

4.2 Héritage

Travail à faire

Modifier le modèle comme sur le support (classes moto et auto). Créer une auto, afficher toutes les autos.
Afficher ensuite les dates des leçons d'un véhicule de numéro d'immatriculation fourni.

4.3 Binding

Travail à faire

Créer un formulaire permettant de créer un nouvel élève en utilisant la procédure stockée fournie avec SqlServer (pInsertEleve)

Créer un formulaire permettant de créer une nouvelle leçon pour un élève inscrit.