'>

Définir un indexeur pour une classe en C sharp

Nous continuons ici à utiliser la classe ListeDePersonnes. Si l est un objet ListeDePersonnes, nous souhaitons pouvoir utiliser la notation
l[i] pour désigner la personne n° i de la liste l aussi bien en lecture (Personne p=l[i]) qu'en écriture (l[i]=new Personne(...)).
Pour pouvoir écrire l[i] où l[i] désigne un objet Personne, il nous faut définir dans la classe ListeDePersonnes la méthode this suivante :
1. public Personne this[int i] {
2. get { ... }
3. set { ... }
4. }
On appelle la méthode this[int i], un indexeur car elle donne une signification à l'expression  obj[i] qui rappelle la notation des
tableaux alors que obj n'est pas un tableau mais un objet. La méthode get de la méthode this de l'objet obj est appelée lorsqu'on écrit
variable=obj[i] et la méthode set lorsqu'on écrit obj[i]=valeur.
La classe ListeDePersonnes dérive de la classe ArrayList qui a elle-même un indexeur :
    public object this[int i] { ... }
Il y a un conflit entre la méthode this de la classe ListeDePersonnes :
 public Personne this[int i]
et la méthode this de la classe ArrayList
 public object this[int i] 

parce qu'elles portent le même nom et admettent le même type de paramètre (int).Pour indiquer que la méthode this de la classe
ListeDePersonnes "cache" la méthode de même nom de la classe ArrayList, on est obligé d'ajouter le mot clé new à la déclaration de
l'indexeur de ListeDePersonnes. On écrira donc :
public new Personne this[int i]{
get { ... }
set { ... }
}
Complétons cette méthode. La méthode this.get est appelée lorsqu'on écrit variable=l[i] par exemple, où l est de type ListeDePersonnes.
On doit alors retourner la personne n° i de la liste l. Ceci se fait avec la notation base[i], qui rend l'objet n° i de la classe ArrayList
sous-jacente à la classe ListeDePersonnes . L'objet retourné étant de type Object, un transtypage vers la classe Personne est nécessaire.
public new Personne this[int i]{
get { return (Personne) base[i]; }
set { ... }
}
La méthode set est appelée lorsqu'on écrit l[i]=p où p est une Personne. Il s'agit alors d'affecter la personne p à l'élément i de la liste l.
public new Personne this[int i]{
get { ... }
set { base[i]=value; }
}
Ici, la personne p représentée par le mot clé value est affectée à l'élément n° i de la classe de base ArrayList.
L'indexeur de la classe ListeDePersonnes sera donc le suivant :
public new Personne this[int i]{
get { return (Personne) base[i]; }
set { base[i]=value; }
}
Maintenant, on veut pouvoir écrire également Personne p=l["nom"], c.a.d indexer la liste l non plus par un n° d'élément mais par un
nom de personne. Pour cela on définit un nouvel indexeur :
1. // indexeur via un nom
2. public int this[string nom] {
3. get {
4. // on recherche la personne
5. for (int i = 0; i < Count; i++) {
6. if (((Personne)base[i]).Nom == nom)
7. return i;
8. }//for
9. return -1;
10. }//get
11.}
La première ligne
public int this[string nom]
indique qu'on indexe la classe ListeDePersonnes par une chaîne de caractères nom et que le résultat de l[nom] est un entier. Cet entier
sera la position dans la liste, de la personne portant le nom nom ou -1 si cette personne n'est pas dans la liste. On ne définit que la
propriété get, interdisant ainsi l'écriture l["nom"]=valeur qui aurait nécessité la définition de la propriété set. Le mot clé new n'est pas
nécessaire dans la déclaration de l'indexeur car la classe de base ArrayList ne définit pas d'indexeur this[string].
Dans le corps du get, on parcourt la liste des personnes à la recherche du nom passé en paramètre. Si on le trouve en position i, on
renvoie i sinon on renvoie -1.
Le programme de test précédent est complété de la façon suivante :
1. using System;
2.
3. namespace Chap2 {
4. class Program2 {
5. static void Main(string[] args) {
6. // une liste de personnes

7. ListeDePersonnes l = new ListeDePersonnes();
8. // ajout de personnes
9. l = l + new Personne("jean", "martin",10) + new Personne("pauline", "leduc",12);
10. // affichage
11. Console.WriteLine("l=" + l);
12. l = l + new Enseignant("camille", "germain",27,60);
13. Console.WriteLine("l=" + l);
14. // changement élément 1
15. l[1] = new Personne("franck", "gallon",5);
16. // affichage élément 1
17. Console.WriteLine("l[1]=" + l[1]);
18. // affichage liste l
19. Console.WriteLine("l=" + l);
20. // recherche de personnes
21. string[] noms = { "martin", "germain", "xx" };
22. for (int i = 0; i < noms.Length; i++) {
23. int inom = l[noms[i]];
24. if (inom != -1)
25. Console.WriteLine("Personne(" + noms[i] + ")=" + l[inom]);
26. else
27. Console.WriteLine("Personne(" + noms[i] + ") n'existe pas");
28. }//for
29. }
30. }
31.}
Son exécution donne les résultats suivants :

1. l=([jean, martin, 10],[pauline, leduc, 12])
2. l=([jean, martin, 10],[pauline, leduc, 12],Enseignant[[camille, germain, 27],60])
3. l[1]=[franck, gallon, 5]
4. l=([jean, martin, 10],[franck, gallon, 5],Enseignant[[camille, germain, 27],60])
5. Personne(martin)=[jean, martin, 10]
6. Personne(germain)=Enseignant[[camille, germain, 27],60]
7. Personne(xx) n'existe pas

Publié par Drupal french Study