Professional Documents
Culture Documents
Info-Sup
tp 12 Avril 2014
Epita
Structure du rendu
La gnricit
2.1
2.2
2.3
2
2
3
Interfaces
3.1
3.2
3.3
3.4
4
5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Les dlgus
Fonctions variadiques . . . .
Fonctions anonymes . . . .
5.2.1 Mthodes anonymes
5.2.2 Expressions lambda
3
3
3
5
6
Fonctions
5.1
5.2
Principe de la gnricit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Crer des classes gnriques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Contraintes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
9
9
9
Exercice
11
6.1
6.2
11
11
Plus en profondeur...
12
Structure du rendu
La structure du rendu pour ce TP ne change pas de celles que vous avez l'habitude de voir. Encore
une fois, login_x est remplacer par votre propre login.
rendu-tpcs12-login_x.zip
- login_x/
- AUTHORS
- Interface
- Interface (tout sauf bin et obj)
- Interface.sln
- MyGenericTab
- MyGenericTab
- MyGenericTab.sln
C#
Info-Sup
tp 12 Avril 2014
2
Epita
La gnricit
2.1
Principe de la gnricit
Les types gnriques permettent de factoriser une partie de votre code en dcrivant des classes ou des
mthodes dont la spcication d'un ou de plusieurs types n'est pas donne jusqu' ce que la classe ou
la mthode soit dclare et instancie. Leur usage permet de gagner en performance et de scuriser les
types lors de la compilation (les gnriques vitent d'utiliser les casts, parfois dangereux).
L'utilisation la plus courante des classes gnriques est avec des collections comme les listes tries, les
tables de hachage, les piles, les les d'attente, les arborescences et autres collections o les oprations telles
que l'ajout et la suppression d'lments de la collection sont excutes de faon relativement similaire
indpendamment du type des donnes qui sont stockes. Voici un exemple de type que vous utilisez depuis
longtemps utilisant les gnriques, le type List :
Aujourd'hui, nous allons aller de l'autre ct de la template en apprenant faire des classes gnriques !
Pour dcrire une classe gnrique, il sut d'expliquer qu'elle dpend d'un type non x.
Voici un petit exemple comment pour expliquer comment procder :
C#
Info-Sup
tp 12 Avril 2014
2.3
Epita
Contraintes
Lorsque vous dnissez une classe gnrique, vous pouvez appliquer des restrictions aux genres de types
que l'utilisateur peut utiliser pour les arguments de type lorsqu'il instancie votre classe. Si l'utilisateur
essaie d'instancier votre classe avec un type qui n'est pas autoris par une contrainte, il en rsultera une
erreur de compilation. Ces restrictions sont appeles des contraintes. Les contraintes sont spcies
l'aide du mot cl contextuel where.
Il existe plusieurs types de contraintes, en voici quelques-unes :
classe : L'argument de type doit tre un type rfrence, y compris tout type classe, interface, dlgu
ou tableau.
<nom d'interface> : L'argument de type doit tre ou doit implmenter l'interface spcie. Plusieurs
contraintes d'interface peuvent tre spcies. L'interface qui impose les contraintes peut galement
tre gnrique.
<nom de classe de base> : L'argument de type doit tre ou doit driver 1 de la classe de base
spcie.
Il y en a d'autres 2 , on vous a list les plus importantes.
Voici un exemple de contrainte :
Interfaces
3.1
Les interfaces sont un concept trs important de la programmation oriente objet. Elle consiste dnir
un ensemble de fonctionnalits comme des mthodes, des proprits, des vnements et des indexeurs.
Les classes ou les structures qui implmentent une interface doivent imprativement implmenter toutes
les mthodes et proprits dnies dans l'interface.
On utilise le mot-clef "interface" pour les dclarer. Il n'y a aucun corps de fonction et on ne peut instancier
une interface malgr sa proximit avec les classes. Une classe et une structure peuvent implmenter
plusieurs interfaces la fois.
Une interface ne peut pas contenir de constantes, de champs, d'oprateurs, de constructeurs d'instances,
de destructeurs ou de types. Elle ne peut pas contenir de membres statiques. Les membres d'interface
sont automatiquement publics et ils ne peuvent contenir aucun modicateur d'accs.
3.2
IEnumerable
Le C# propose pleins d'interfaces dont la majorit utilise les gnriques. N'hsitez pas vous renseigner dessus. En attendant, voici un exemple d'interface de C# sexy : IEnumerable est une interface
permettant de parcourir un conteneur. Celle-ci permet entre autres d'utiliser un objet dans une boucle
"foreach". La seule mthode implmenter pou respecter cette interface est :
IEnumerator GetEnumerator()
3.3
Rien ne vous empche de dnir votre propre interface. Par convention, leur nom commence par un
"I" et les deux premires lettres sont en majuscules. Exemple :
1. Hritage, toussa toussa...
2. Voir "Plus en profondeur..."
3. Voir la partie "Interfaces"
C#
Info-Sup
tp 12 Avril 2014
Epita
interface IDimensions
{
float getLength();
float getWidth();
}
class Box : IDimensions
{
float lengthInches;
float widthInches;
Box(float length, float width)
{
lengthInches = length;
widthInches = width;
}
// Implmentation implicite mais obligatoire de IDimensions
float getLength() { return lengthInches; }
float getWidth() { return widthInches; }
static void Main()
{
Box box1 = new Box(30.0f, 20.0f);
Voici le mme exemple mais avec une implmentation explicite des interfaces :
C#
Info-Sup
tp 12 Avril 2014
Epita
interface IDimensions
{
float getLength();
float getWidth();
}
class Box : IDimensions
{
float lengthInches;
float widthInches;
Box(float length, float width)
{
lengthInches = length;
widthInches = width;
}
// Implmentation explicite mais obligatoire de IDimensions
float IDimensions.getLength() { return lengthInches; }
float IDimensions.getWidth() { return widthInches; }
static void Main()
{
Box box1 = new Box(30.0f, 20.0f);
IDimensions dimensions = (IDimensions)box1;
Console.WriteLine("Length {0}", dimensions.getLength());
Console.WriteLine("Width {0}", dimensions.getWidth()):
}
}
3.4
Exercice
C#
Info-Sup
tp 12 Avril 2014
4
Epita
Les dlgus
Les dlgus (delegate en anglais) est un type qui dnit une signature de mthode (et son type
de retour). Quand vous instanciez un dlgu vous associez l'instance de votre dlgu (la variable pour
ceux qui seraient un peu perdus) avec une mthode dont la signature est la mme que celle dnie dans
le dlgu.
Voici quoi a ressemble :
intFunctions = minusFortyTwo;
Console.WriteLine(intFunctions(x));
intFunctions(x)
Ceci appelle la mthode 4 qui est dans le dlgu intFunctions. Une fois votre dlgu instanci il peut
s'utiliser exactement comme une fonction.
Pour mieux comprendre ce qu'est un dlgu entrainez vous, faites vos propres essais.
Quel est l'utilit ?
Voici un exemple. Vous crez une classe pour reprsenter votre structure de donnes prfre (liste,
arbre, tas de Fibonacci 5 ), avec notamment une fonction de tri dans cette structure. Mais vous tes super
forts, du coup vous avez fait plusieurs algorithmes pour trier vos donnes. Quand vous appelez la fonction
de tri vous voulez pouvoir dire "je veux que tel algorithme soit appel".
Vous pourriez faire :
4. Une instance de dlgu peut contenir plusieurs mthodes. En eet vous pouvez crire intFunctions = minusFortyTwo ;
puis intFunctions += square ; Je vous laisse voir ce que a fait par vous mme.
5. celui qui implmente un tas de Fibonnaci pendant le TP aura beaucoup de points bonus
C#
Info-Sup
tp 12 Avril 2014
Epita
Fonctions
Fonctions variadiques
Vous savez depuis longtemps comment crer des fonctions avec arguments. Mais savez-vous crer des
fonctions avec un nombre variable d'arguments ?
Prenons un exemple, vous avez une fonction qui va crire dans un chier (avec un Stream) dirents
objets. Pour cela, vous pourriez crer une fonction de ce genre :
sw.Close();
stream.Close();
C#
Info-Sup
tp 12 Avril 2014
Epita
Comme vous pouvez le voir, tout a n'est pas trs pratique si on veut eectuer des critures la
suite. Bien entendu, on pourrait changer le "object l" par un tableau d'Object ("object[] l"), puis faire
un parcours, tout a nous obligerait crer un tableau avant de faire l'appel la fonction WriteInFile.
C'est l que le terme "variadique" entre en scne. Le principe des fonctions variadiques est simple :
permettre l'appel une fonction avec un nombre variable d'objets. Pour ceux qui ont dj cod en C,
rappelez-vous la fonction "printf".
Pour raliser ceci, nous avons besoin d'un nouveau mot cl : params. Voici la dnition et l'exemple
fournis par MSDN :
The params keyword lets you specify a method parameter that takes an argument where the
number of arguments is variable.
No additional parameters are permitted after the params keyword in a method declaration,
and only one params keyword is permitted in a method declaration.
Comment vous pouvez le voir, le mot params s'utilise de cette manire "(params typename[] name)".
Vous pouvez appeler la fonction avec soit un tableau du type "typename", soit avec plusieurs lements
du type "typename" spars par une virgule.
Dans UseParams2, vous pouvez remarquer l'utilisation du mot cl ob ject, qui peut en fait reprsenter
tous les types possibles.
Il reprsente en fait un alias (un raccourci, si vous prfrez) pour la classe Object. Cette classe est en fait
la mre de toute chose, le pre de vos pres, la mre du ls de votre soeur, et mme celle de votre feu
grand oncle Marcel.
Plus srieusement, maintenant que vous tes plus ou moins familier avec la notion d'hritage, nous pouvons vous dire la vrit : toutes les classes hritent directement ou indirectement de cette classe. Vous
trouverez plus d'informations sur MSDN ou auprs des vos ACDCs (encore une fois). C'est donc pour
cette raison que vous pouvez placer le mot object pour reprsenter tous les types : ils hritent tous de
lui. Dans le premier exemple, o l'on crivait " Stream stream = new FileStream(...) ", le compilateur
ne sortait pas d'erreurs car FileStream hrite de Stream, et donc la conversion de FileStream vers un
Stream ne posent aucun problme (notez que l'inverse n'est pas vrai, nous vous laissons deviner pourquoi).
Maintenant que vous savez tout ceci, essayez d'appeler UseParams2 avec comme paramtre "new
int[3]1, 2, 3". Nous vous laissons deviner tout seul pourquoi le rsultat n'est pas celui que vous attendiez.
8
C#
Info-Sup
tp 12 Avril 2014
5.2
Epita
Fonctions anonymes
Nous allons voir ce que sont les fonctions anonymes. Comme vous pouvez vous en douter, une fonction
anonyme est une fonction "sans nom". a ne vous aide pas beaucoup, et puis une fonction sans nom c'est
un peu con, non ? Comment l'appeler si elle n'a pas de nom ?
Allons voir ce que MSDN nous dit l dessus.
Une fonction anonyme est une instruction ou expression "inline" qui peut tre utilise partout
o un type dlgu est attendu. Vous pouvez l'utiliser pour initialiser un dlgu nomm ou
la passer la place d'un type dlgu nomm en tant que paramtre de mthode. MSDN
Retenez donc qu'une fonction anonyme peut tre utilise partout o un dlgu est attendu.
Entrons plus dans le dtail pour voir deux types de fonctions anonymes : les expressions lambda et
les mthodes anonymes (notez la dirence entre fonctions anonymes et mthodes anonymes ).
5.2.1
Mthodes anonymes
Les mthodes anonymes servent entre autres passer un bloc de code en paramtre de dlgu,
c'est dire que vous pouvez crer la mthode qui est encapsule par votre dlgu directement dans
l'instanciation de celui-ci.
Voici un exemple :
Expressions lambda
Les expressions lambda (lambda expressions en anglais, oui oui c'est une remarque utile). Encore
une fois, une explication venant de MSDN (MSDN est votre ami).
A lambda expression is an anonymous function that you can use to create delegates or expression tree types. By using lambda expressions, you can write local functions that can be passed
as arguments or returned as the value of function calls. Lambda expressions are particularly
helpful for writing LINQ query expressions.
To create a lambda expression, you specify input parameters (if any) on the left side of the
lambda operator =>, and you put the expression or statement block on the other side. For
example, the lambda expression x => x * x species a parameter that's named x and returns
the value of x squared.
Si vous ne comprenez pas la partie sur les types d'arborescence ou sur LINQ c'est normal, et ne vous
inquitez pas nous n'utiliserons pas ces notions pendant le TP.
La syntaxe encore une fois est assez simple 6 :
C#
Info-Sup
tp 12 Avril 2014
Epita
Si vous n'avez qu'un seul paramtre, alors les parenthses sont facultatives. Le type des paramtres est
lui aussi facultatif dans certains cas (quand le compilateur n'arrive pas trouver le type des paramtres
tout seul).
10
C#
Info-Sup
tp 12 Avril 2014
6
Epita
Exercice
6.1
Dans cette partie, on va implmenter notre propre structure de donnes : un tableau dynamique.
Dynamique signie que sa taille peut changer. Si on arrive la taille max du tableau, on le ralloue avec
une taille plus grande tout en rcuprant ses donnes.
Etant donn que vous avez appris de nouvelles notions lors de la lecture de ce TP, on va les mettre
en application : on va implmenter un tableau dynamique gnrique, tout en se servant d'interface, de
dlgus et de fonctions anonymes.
On vous donnera les mthodes implmenter ainsi que leur signature et ce qu'elles doivent faire, et
quelle "notion" utiliser... vous de faire le reste !
Notre classe, se nommera MyGenericTab. Attention ! Elle doit tre gnrique, et on vous impose une
contrainte sur le type : il doit hrit de l'interface IComparable.
Elle aura comme attributs :
Un tableau de type T non initialis
Un entier contenant le nombre d'lments actuels dans le tableau
Les mthodes :
Un constructeur : initialise le tableau ainsi que son nombre d'lments contenus
public MyGenericTab<T>() { ... }
Insert : ajoute un lment la premire position libre du tableau, si le tableau est plein, on le
ralloue en doublant la taille du tableau !
public void Insert(T elt) { ... }
Delete : supprime l'lment pass en argument dans le tableau, et on redcale tous les lments
pour qu'il n'y ait pas de trous. Renvoie vrai si la suppression a march, faux sinon.
public bool Delete(T elt) { ... }
At : renvoie la ime valeur. Dclenche une exception si l'index est invalide.
public T At(int i) { ... }
mapDelegate : dlgu utiliser pour map. Il est dclarer l'extrieur de la classe.
public delegate T mapDelegate<T>(T elt);
Map : Applique le dlgu pass en paramtre tous les lments du tableau
public void Map(mapDelegate funct) { ... }
Sort : Trie le tableau en se servant de la mthode CompareTo de IComparable
public void Quicksort(int left, int right) { ... }
Print : Ache en vert les lments pour lesquels le prdicat est pass en paramtre (dlgu), sinon
ache l'lment en rouge.
public void Print(/* dlgu qui renvoit un boolen et prend en paramtre
un lment T */) { ... }
6.2
Bonii
11
C#
Info-Sup
tp 12 Avril 2014
7
Epita
Plus en profondeur...
Cette partie est l pour ceux qui dsirent en savoir plus, car ce qui a t montr n'englobe pas toutes
les fonctionnalits des notions cites en C#.
On vous montre juste quelques particularits qui existent, si vous voulez en savoir plus, google est
votre ami, ou protez-en pour essayer de mettre une colle votre ACDC.
Type valeur
Type rfrence
Mot cl default pour la gnricit
Typage scuris lors de la compilation grce la gnricit
Contrainte new() sur un paramtre gnrique
On peut implmenter un membre d'interface explicitement : void ISampleInterface.SampleMethod(),
mais c'est pas aussi simple...
12