Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

C# 2.0 : Les class "Generic" : Ce qu’elles peuvent vous apporter

18 réponses
Avatar
Alexandre Roba
On a écrit beaucoup de chose sur les génériques et comme beaucoup d’autres
techniques, ils ont leurs défenseurs et leurs détracteurs. D’un coté il y a
les puristes de l’objet qui disent qu’ils ne respectent pas les règles du jeu
OO, mais de l’autre il y a les habitués des « Template » qui eux les trouvent
indispensable. Que peut-on donc nous en penser.

Personnellement j’essaye de rester pragmatique. J’y ai donc jeté un œil
attentif et j’ai essayé de voir comment je pouvais améliorer ma vie de
développeur avec ces class génériques.

<B>Introduction</b>

Les class génériques sont des squelettes de code ou le paramètre est un
type. Supposons que vous développiez une class contenant une liste d’entier.
Il serait pratique de pouvoir utiliser le même code pour définir une liste de
nombre décimaux.

Avec les génériques c’est plutôt facile. On commence par définir la classe
générique.

public class List<T>
{
private ArrayList list = new ArrayList();

public int Add(T input)
{
return this.list.Add(input);
}
public T this[int index]
{
get { return (T)list[index]; }
set { list[index] = value;}
}

}

Et puis pour l’utiliser avec un entier ou un nombre décimal on fait :

List<int> listentiers = new List<int>();
List<double> listdecimaux = new List<double>();

listentiers.Add(12);
listdecimaux.Add(12.3);

C’est aussi facile que ca.

Le paramètre <T> ne se limite pas, comme ici, à l’utilisation de type
simple. Notre générique peut être utilisé avec des types plus complexes tels
qu’une class ou une structure.

Voyons maintenant comment on peut en tirer profité dans notre vie de tous
les jours.

<b>Utilisation des classes génériques</B>
Lorsque j’ai besoin de créer une class qui représente une collection
d’entités, plusieurs choix s’offre à moi :

1. J’utilise une collection non typé comme ancêtre. L’inconvénient ici c’est
que la méthode me permettant d’ajouter des entités ne sera pas typée. Elle me
permettra d’ajouter des entités de n’importe qu’elle type. Bien sur je peux
faire des vérifications avant d’insérer l’élément et bien sur je peux ajouter
des méthodes d’ajout typé. Mais est-ce vraiment le plus pratique des moyens
?...
2. Je développe une class spécifique en incluant l’implémentation
d’interface de collection tels que « IEnumerable », « IList »… Je contrôle
donc tout l’implémentation ici mais je dois écrire pas mal de code.

Il existe d’autres moyens tels que créée sa propre class de collection
héritant de class comme « CollectionBase » et de faire hériter toutes vos
collections de cette nouvelle class… Mais ces moyens ne sont qu’une
combinaison des deux cas précédents.

Voyons comment les classes génériques peuvent nous faciliter la vie lors de
la création de collection typé.

Commençons par regarder quelques une des class génériques qui sont mises à
notre disposition avec le Framework .NET 2.0. On peut y voir :
• List<T>
• Dictionary<TKey,TValue>
• LinkedList<T>
• Queue<T>
• SortedDictionary<TKey,TValue>
• Stack<T>
• …

Concentrons nous sur List<T> pour construire une collection typé d’entité.
Soit « Personne » cette entité :
class Personne
{
private string prenom;
public string Prenom
{
get { return prenom; }
set { prenom = value; }
}
private string nomdefamille;
public string Nomdefamille
{
get { return nomdefamille; }
set { nomdefamille = value; }
}
}

Créons notre liste typé.

List<Personne> personnes = new List<Personne>();

Ajoutons un élément à cette liste :

personnes.Add(new Personne());
personnes[0].Prenom = "Albert";
personnes[0].Nomdefamille = "Einstein";

Pratique non ? Et on peut bien sur faire la même chose pour une pile, une
queue, une liste ordonnée…

Lorsque l’on veut parcourir une liste non typé en utilisant « foreach() » il
suffit que notre la liste implémente l’interface « IEnumerable » qui est non
typé.

Arraylist list = new ArrayList();
foreach (int i in list){...}
foreach (object o in list){...}
foreach (mauvaisobject o in list){...}

Fonctionnera parfaitement à la compilation…Mais lors de l’exécution on peut
avoir des surprises…

Pour remédier à ce problème, nous avons maintenant à notre disposition
l’interface « IEnumerable<> » Chaque class générique qui implémente cette
interface devient parcourable de manière typé !

//Fonctionne
foreach (Personne p in personnes){...}
//Erreur de compilation
foreach (int i in personnes){...}

Ce qui nous permet d’être certain lors de la compilation du type qui se
trouve réellement dans la liste.
Je ne sais pas pour vous mais je pense que rien que ca va me permettre de
rendre mon code plus solide.

Dans le namespace « System.Collection.Generic » nous pouvons aussi trouver
la version générique des interfaces suivantes :
• ICollection<>
• IDictionary<>
• IList<>
• IComparer<>
• IEnumerator<>
• IEqualityComparer<>

<b>Pour conclure</B>

Après avoir passé quelque temps sur les classes génériques je peux dire
maintenant qu’elles me feront gagner énormément de temps.
D’abord parce que le Framework contient certaines des classes du namespace
« System.Collection » implémenté avec des génériques me donnant ainsi un
moyen rapide et facile de les utiliser. Ensuite parce que je pense qu’une
bonne utilisation des classes génériques peut m’amener à un meilleur niveau
de réutilisation de code.

10 réponses

1 2
Avatar
Tsunoo Rhilty
Un exemple ici:
http://msdn.microsoft.com/msdnmag/issues/03/09/NET/default.aspx?fig=true#fig1

Perso: je trouve que ca alourdi énormément le code source.


Après avoir passé quelque temps sur les classes génériques je peux dire
maintenant qu'elles me feront gagner énormément de temps.
D'abord parce que le Framework contient certaines des classes du namespace
« System.Collection » implémenté avec des génériques me donnant ainsi un
moyen rapide et facile de les utiliser.



Ca ne te fait pas gagner du temps car "System.Collection" existait déjà.
Ca en fait gagner à MS.

Au contraire tu as plus de code à tapper.
Exemple
AVANT:
Node head = new Node(5, null);
head = new Node(10, head);
head = new Node(15, head);APRES:
Node<Int32> head = new Node<Int32>(5, null);
head = new Node<Int32>(10, head);
head = new Node<Int32>(15, head);
Je ne suis pas du tout contre les generics mais ayant vu beaucoup de code en
C++ avec template programmé par d'autres personnes. Je peux dire que la
facilité de (re)lecture est bien mis de côté.
Helas.

Par contre je suis pour parce que finallement ce n'est pas imposé... on peut
garder son ancien style et donc chacun peut faire son choix.
Avatar
Ambassadeur Kosh
comme dirait Lloyd Dupont
"42, mais quelle est la question ?"

pour la suite :
http://www.codeproject.com/csharp/stldotnet.asp

et petit détail : implanter IEnumerable permet d'obtenir la meme "detection
de type" pour foreach que IEnumerable<T>. les generics n'y sont pour rien
(ils permettent juste de "factoriser" l'ecriture), c'est implicit/explicit
qui fait tout.

public class DummyList : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator() ...
public DummyEnumerator GetEnumerator() ...
}

public class DummyEnumerator : IEnumerator
{
Dummy Current {...}
object IEnumerator.Current {...}
}

voila voila...
Avatar
Arnaud Debaene
Alexandre Roba wrote:
On a écrit beaucoup de chose sur les génériques et comme beaucoup
d'autres techniques, ils ont leurs défenseurs et leurs détracteurs.
D'un coté il y a les puristes de l'objet qui disent qu'ils ne
respectent pas les règles du jeu OO,



Je serais assez intéressé par une argumentation sérieuse de cette "thèse"...
L'un des premiers apports des génériques, c'est la "type-safety" des
collections par rapport à une implémentation basée sur Object qui réclame
des downcasts dans tous les sens. Si la "type-safety" n'est pas "dans les
règles de jeu OO" (c'est quoi çà au juste ces règles du jeu????), je pense
qu'on a pas la même idée de ce que c'est que l'objet....

Arnaud
MVP - VC
Avatar
Cyrille37
Arnaud Debaene wrote:
Alexandre Roba wrote:

On a écrit beaucoup de chose sur les génériques et comme beaucoup
d'autres techniques, ils ont leurs défenseurs et leurs détracteurs.
D'un coté il y a les puristes de l'objet qui disent qu'ils ne
respectent pas les règles du jeu OO,




Je serais assez intéressé par une argumentation sérieuse de cette "thèse"...
L'un des premiers apports des génériques, c'est la "type-safety" de s
collections par rapport à une implémentation basée sur Object qui réclame
des downcasts dans tous les sens. Si la "type-safety" n'est pas "dans l es
règles de jeu OO" (c'est quoi çà au juste ces règles du jeu???? ), je pense
qu'on a pas la même idée de ce que c'est que l'objet....



Bien d'accord avec Arnaud.

Et j'apporte un peu d'essence sur le feu en ajoutant :

Tout dépend de l'école OO à laquelle on se réfère, Comme d'habi tude il y en a plusieures. ;o)

Il y a notamment une des philosophies Orientée Objet qui définie le t ypage de cette façon :
un objet est du bon type s'il possède la méthode que l'on souhaite lu i voir exécuter.
Il me semble que ça vient de SmallTalk, puis Javascript. Corrigez moi s i je me trompe.

Bye bye
cyrille, un objet qui n'vous veut que du bien ;o)
Avatar
Lloyd Dupont
> comme dirait Lloyd Dupont
"42, mais quelle est la question ?"



c'est vrai, je pourrais dire ca ;-)
Avatar
Alexandre Roba
Ambassadeur Kosh,

C'est exact, merci pour la correction.

Alexandre Roba

"Ambassadeur Kosh" a écrit :

comme dirait Lloyd Dupont
"42, mais quelle est la question ?"

pour la suite :
http://www.codeproject.com/csharp/stldotnet.asp

et petit détail : implanter IEnumerable permet d'obtenir la meme "detection
de type" pour foreach que IEnumerable<T>. les generics n'y sont pour rien
(ils permettent juste de "factoriser" l'ecriture), c'est implicit/explicit
qui fait tout.

public class DummyList : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator() ...
public DummyEnumerator GetEnumerator() ...
}

public class DummyEnumerator : IEnumerator
{
Dummy Current {...}
object IEnumerator.Current {...}
}

voila voila...





Avatar
Alexandre Roba
Salut Arnaud,

Merci d'avoir prit le temps de lire le post. Ce que j'ai pu lire contre les
generic dans le design OO est qu'ils ne rentrent pas vraiment dans une
relation de generalistion, de composition, de generalisation ou
d'association. Ils ne sont considere que comme des "moyens techniques" pour
ameliorer la reutilisation et le type-safety.

Le but du post n'etait pas vraiment de commencer une gueguerre sur ce qui
est OO ou pas OO. D'ailleurs je ne pense pas prendre position la dessus...
Mais je prends position sur le fait que les generic peuvent apporter une plus
value de maniere tres rapide.

Son but etait juste d'essayer de montrer comment on peut commencer à
utiliser les generic et cela tres facilement.

Bien à toi,

Alexandre Roba

"Arnaud Debaene" a écrit :

Alexandre Roba wrote:
> On a écrit beaucoup de chose sur les génériques et comme beaucoup
> d'autres techniques, ils ont leurs défenseurs et leurs détracteurs.
> D'un coté il y a les puristes de l'objet qui disent qu'ils ne
> respectent pas les règles du jeu OO,

Je serais assez intéressé par une argumentation sérieuse de cette "thèse"...
L'un des premiers apports des génériques, c'est la "type-safety" des
collections par rapport à une implémentation basée sur Object qui réclame
des downcasts dans tous les sens. Si la "type-safety" n'est pas "dans les
règles de jeu OO" (c'est quoi çà au juste ces règles du jeu????), je pense
qu'on a pas la même idée de ce que c'est que l'objet....

Arnaud
MVP - VC





Avatar
adebaene
Cyrille37 a écrit :

Arnaud Debaene wrote:
> Alexandre Roba wrote:
>
>>On a écrit beaucoup de chose sur les génériques et comme beaucoup
>>d'autres techniques, ils ont leurs défenseurs et leurs détracteurs.
>>D'un coté il y a les puristes de l'objet qui disent qu'ils ne
>>respectent pas les règles du jeu OO,
>
>
> Je serais assez intéressé par une argumentation sérieuse de cette "thèse"...
> L'un des premiers apports des génériques, c'est la "type-safety" des
> collections par rapport à une implémentation basée sur Object qui réclame
> des downcasts dans tous les sens. Si la "type-safety" n'est pas "dans l es
> règles de jeu OO" (c'est quoi çà au juste ces règles du jeu???? ), je pense
> qu'on a pas la même idée de ce que c'est que l'objet....

Bien d'accord avec Arnaud.

Et j'apporte un peu d'essence sur le feu en ajoutant :

Tout dépend de l'école OO à laquelle on se réfère, Comme d'habi tude il y en a plusieures. ;o)

Il y a notamment une des philosophies Orientée Objet qui définie le t ypage de cette façon :
un objet est du bon type s'il possède la méthode que l'on souhaite lu i voir exécuter.
Il me semble que ça vient de SmallTalk, puis Javascript. Corrigez moi s i je me trompe.



Oui, 'est le typeage dynamique, mais il se trouve que .NET (et C#) ont
pris l'option du typage statique (en fournissant des capacités de
réflexion et de downcasts dynamiques avec vérification du type réel
de l'objet, mais ca reste du typage statique).

Arnaud
MVP - VC
Avatar
Oriane
Pour avoir utilisé des templates C++, je suis assez dubitatif par rapport à
ces techniques, qui donnent (dans le cas de C++) un code plus lent, un
débuggage plus difficile.

"Alexandre Roba" a écrit dans le
message de news:
On a écrit beaucoup de chose sur les génériques et comme beaucoup d'autres
techniques, ils ont leurs défenseurs et leurs détracteurs. D'un coté il y
a
les puristes de l'objet qui disent qu'ils ne respectent pas les règles du
jeu


[...]
Avatar
Alexandre Roba
Arnaud,

Es-tu sur qu'il s'agisse de typage dynamique? Je pense que le typage
dynamique siginifique que l'object se voit attribuer son type lors de sa
creation et qu'il se voit capable de dire quel est son type. Le fait qu'il
implemente une methode ne donne pas son type our autant.




"" a écrit :


Cyrille37 a écrit :

> Arnaud Debaene wrote:
> > Alexandre Roba wrote:
> >
> >>On a écrit beaucoup de chose sur les génériques et comme beaucoup
> >>d'autres techniques, ils ont leurs défenseurs et leurs détracteurs.
> >>D'un coté il y a les puristes de l'objet qui disent qu'ils ne
> >>respectent pas les règles du jeu OO,
> >
> >
> > Je serais assez intéressé par une argumentation sérieuse de cette "thèse"...
> > L'un des premiers apports des génériques, c'est la "type-safety" des
> > collections par rapport à une implémentation basée sur Object qui réclame
> > des downcasts dans tous les sens. Si la "type-safety" n'est pas "dans les
> > règles de jeu OO" (c'est quoi çà au juste ces règles du jeu????), je pense
> > qu'on a pas la même idée de ce que c'est que l'objet....
>
> Bien d'accord avec Arnaud.
>
> Et j'apporte un peu d'essence sur le feu en ajoutant :
>
> Tout dépend de l'école OO à laquelle on se réfère, Comme d'habitude il y en a plusieures. ;o)
>
> Il y a notamment une des philosophies Orientée Objet qui définie le typage de cette façon :
> un objet est du bon type s'il possède la méthode que l'on souhaite lui voir exécuter.
> Il me semble que ça vient de SmallTalk, puis Javascript. Corrigez moi si je me trompe.

Oui, 'est le typeage dynamique, mais il se trouve que .NET (et C#) ont
pris l'option du typage statique (en fournissant des capacités de
réflexion et de downcasts dynamiques avec vérification du type réel
de l'objet, mais ca reste du typage statique).

Arnaud
MVP - VC




1 2