Vous êtes sur la page 1sur 42

1er avril 2008

1 C# : Lessentiel en concentr
C# : Lessentiel en concentr
Sommaire
1 Introduction ..................................................................................................................................... 3
1.1 Quest-ce quun langage de programmation .......................................................................... 3
1.2 Pourquoi lorient objet .......................................................................................................... 3
1.3 Un peu dhistoire ..................................................................................................................... 3
1.4 Un exemple ............................................................................................................................. 4
1.5 Gestion de la mmoire vive en .NET ....................................................................................... 5
2 La syntaxe procdurale : logique C/C++ applique en C# ............................................................... 5
2.1 Variables, oprateurs numrique et types. ............................................................................. 6
2.1.1 Les types .......................................................................................................................... 6
2.1.2 Les oprateurs ................................................................................................................. 7
2.1.3 Exemple de calculs et de dclaration de variable ........................................................... 7
2.1.4 Les chaines de caractres : quelques dtails ................................................................... 8
2.1.5 Les valeurs clefs et les types nullable .............................................................................. 9
2.1.6 Le Cast ............................................................................................................................. 9
2.2 La condition: if else switch/case oprateur ternaire .................................................... 10
2.3 Les boucles: while do for goto ...................................................................................... 12
2.3.1 While.............................................................................................................................. 12
2.3.2 Do while ......................................................................................................................... 13
2.3.3 For .................................................................................................................................. 13
2.3.4 Goto ............................................................................................................................... 13
2.3.5 Sortie de boucles : Break-Continue ............................................................................... 14
2.4 Array enum struct ............................................................................................................ 15
2.4.1 foreach ........................................................................................................................... 16
2.5 Gestion des erreurs : try-catch finally ................................................................................ 16
2.6 Instructions prprocesseurs .................................................................................................. 18
2.7 Le code unsafe et checked / unchecked .................................................................... 18
3 Lorient Objet en C# ..................................................................................................................... 20
3.1 Introduction ........................................................................................................................... 20
3.2 Using ...................................................................................................................................... 20
3.3 Instanciation .......................................................................................................................... 20




1er avril 2008
2 C# : Lessentiel en concentr
3.3.1 Lattribut et le modificateur daccs ............................................................................. 21
3.4 La proprit ........................................................................................................................... 22
3.5 Static ...................................................................................................................................... 23
3.6 Les mthodes ........................................................................................................................ 24
3.6.1 Retour sur Main ............................................................................................................. 24
3.6.2 Constructeur / destructeur ........................................................................................... 25
3.6.3 La surcharge .................................................................................................................. 27
3.6.4 Delegate......................................................................................................................... 28
3.6.5 Les vnements ............................................................................................................. 29
3.6.6 Mthodes anonymes et Expressions lambda ................................................................ 31
3.6.7 Mthode dextension. ................................................................................................... 33
3.6.8 Itrateurs ....................................................................................................................... 34
3.7 Lhritage, le polymorphisme et les interfaces ..................................................................... 35
3.7.1 Introduction ................................................................................................................... 35
3.7.2 Exemples dhritage : les exceptions et throw ............................................................. 36
3.7.3 Redfinition de mthodes et dattributs ....................................................................... 37
3.7.4 Les interfaces ................................................................................................................. 38
3.7.5 Les attributs ................................................................................................................... 40
4 Conclusion ..................................................................................................................................... 41















1er avril 2008
3 C# : Lessentiel en concentr
1 Introduction
Comme ce chapitre rsume de manire synthtique le langage de programmation, si vous
navez aucune connaissance en orient objet, java ou programmation je vous recommande de lire au
moins deux fois ce cours pour donner une meilleure cohsion lensemble des connaissances qui en
ressortent. Vous verrez quil y a beaucoup de rfrences des sous-parties qui seront traites en
aval. Il marrivera souvent de coder plusieurs fois des exemples identiques ou trs proche avec des
mots clefs diffrents pour vous permettre de comprendre par analogie et vous viter de relire
lensemble de la source avec attention pour comprendre. Dans les premires parties il marrivera de
dire fonction la place de mthode , cest parce que cest plus parlant pour beaucoup, cet
abus de langage volontaire sera clairci dans la partie rserve aux mthodes.

1.1 Quest-ce quun langage de programmation
C#, je ne pense pas vous lapprendre est un langage de programmation. Ces langages ne sont
pas le mode de pens de la machine qui elle ne comprend que des instructions binaires dpendantes
du processeur. Ces langages ont pour but dtre plus lisible et plus pratique que lassembleur pour
simplifier la vie des dveloppeurs. Le C et le C++ sont des langages compils qui sont donc
transforms directement en instructions processeur. En .NET, ce nest pas le cas la compilation
donne un code (MSIL/Microsoft Intermediate Language) qui est interprt par un logiciel
(interprteur). Il faut donc retenir que les langages sont des normes de dveloppement qui
cherchent souvent un compromis entre le confort, la rapidit de dveloppement et la performance.
Ces normes sont accompagnes doutils tel un compilateur.

Du fait que le code compil MSIL soit commun au langage .NET utilis, on peu dire que le C# et
le VB.NET sont deux langages de programmation ayant un confort diffrent mais des performances
trs similaires.

1.2 Pourquoi lorient objet
Lorient objet t introduit par le langage SmallTalk (dvelopp par la socit Xerox) en
1972. Lorient objet est un ensemble de rgles, de concepts, doutils du langage de programmation
pour rendre le dveloppement plus ais grce au groupement dlments. Les objets sont donc des
entits qui permettent de grouper ensemble des fonctions et des variables en facilitant leurs gestions
par groupe et en ouvrant de multiples possibilits. Dfinir un objet peut paraitre comme ajouter un
outil, Le framework .NET apporte lui un set imposant dobjets existants. Un langage Orient objet
nest pas les objets, mais une syntaxe et des mots clefs pour les manipuler et les crer. Bien que nous
allons utiliser des objets du framework ce cour visera vous apprendre le langage.

Lorient objet permet la gestion densemble, le groupement, lisolation des donnes et des
fonctions. Cet ensemble de concepts et doutils permet par exemple de grouper dans un coin les
objets pour accder aux donnes distinctement des objets qui servent a faire linterface avec
lutilisateur et des objets qui servent appliquer les calculs et procdure logiques de fond. De ce fait
nous pourrons disposer dun code simple et lisible.

1.3 Un peu dhistoire
Le C# est un langage rcent apparu en 2001, il est principalement inspir par le Java (1995)
mais aussi par le C++. Ce langage dont le nom se prononce C-Sharp t cr par Microsoft t
normalis par lECMA lanne de sa sortie (puis par lISO deux ans plus tard). Il y a eu trois version du
C# implmentant toujours quelques fonctionnalits supplmentaires. Le C# tant un produit du
framework .NET leurs volutions sont trs lies. Le C# 2.0 est sorti avec le framework 2.0, le C#3.0 lui




1er avril 2008
4 C# : Lessentiel en concentr
bien quutilisable sur le framework2.0 arrive nativement et prend vraiment tout son intrt dans le
framework 3.5 avec le LINQ. Pour utiliser la syntaxe du C#3.0 il faut utiliser le compilateur adapt
dans un environnement cible 2.0 ou suprieur. Ce compilateur est notamment disponible et
implment avec VisualStudio 2008.

1.4 Un exemple
Ce tutorial est ax sur le langage et la syntaxe du C#, dans le cas ou vous seriez sous Windows,
vous pouvez essayer Visual Studio Express ou SharpDevelop (voire le mode C# de Eclipse). Dans le cas
ou vous seriez sous Linux ou Mac, je vous encourage lire ds prsent les deux premiers tutoriels
sur Mono. Il est important de connaitre ses outils et de les avoir fonctionnels pour pouvoir se
concentrer sur la logique de programmation.

Remarque : Pour les inconditionnels de la ligne de commande, ajoutez votre variable
denvironnement Path : C:\WINDOWS\Microsoft.NET\Framework\v3.5 , vous pourrez compiler les
exemples que vous aurez enregistr dans des fichiers texte en faisant csc.exe monpremiercode.cs
puis excuter le programme monpremiercode.exe , vous pourrez aussi ajouter des options de
compilation, pour voir celles disponible excutez : csc.exe /? .
Voici un code affichant dans un terminal Bonjour ! . Le code propos est rduit sa plus
simple expression. Mme les projets console par dfaut des environnements de dveloppement
intgrs sont plus consquent.
Pour linstant nous nous concentrerons sur le contenu des accolades qui suivent Main( ) . Les
accolades sont prcdes de mots clefs et noms qui servent former une structure dexcution.
Cette structure relevant de lorient objet est ncessaire lexcution mais elle ne sera explique
seulement quaprs avoir acquis les bases de la logique procdurale.

C#

static class Program
{
static void Main()
{
// Dans les exemples qui suivent nous placerons notre code ici
System.Console.WriteLine("Bonjour !");
}
}

Vous avez remarqu que sur la premire ligne de la zone tudie (la ligne verte) jai crit un
texte libre en franais. Cette ligne commence par // . Ce symbole est un symbole de commentaire
qui dit au compilateur de ne pas interprter la fin de la ligne. Il marrivera souvent de vous faire des
remarques dans ces commentaires qui sont partie intgrante du tutoriel.

Il existe aussi une autre convention de commentaire qui au lieu dchapper la fin de la ligne,
chappe jusqu un symbole de fermeture. Ces commentaires l souvrent avec /* et se ferment
avec */ (vous aurez un exemple dans le prochain extrait de code). Il y a une syntaxe qui permet
de gnrer de la documentation partir des commentaires, si vous devez travailler en quipe ou
pour une entreprise, gnrer une documentation qui permettra votre successeur de prendre la
relve savre important (page sur la documentation du code en C#). Si vous vous intressez cette
syntaxe, cette page vous expliquera lessentiel. Cela dit le contenu de cette page contient des
donnes assez techniques de ce fait il pourrait tre pertinent dy jeter un il seulement aprs avoir
fini de lire ce tutorial.





1er avril 2008
5 C# : Lessentiel en concentr
System.Console.WriteLine est appel avec Bonjour ! en argument, on ajoute cela un ;
pour spcifier excute a puis on passe la suite . On appelle chaque lment qui suivi dun ;
une instruction. Il peut tres sur une ou plusieurs lignes. Lorsque Main a excut la dernire
instruction quil contient le programme prend fin. Si vous avez lanc graphiquement votre
application, la fentre console se fermera car la fin du programme entraine la fin de la console. Je
sais que a nexplique pas tout lextrait de code mais venons y progressivement avec cette
architecture en tte. Retenez bien que chaque imbrication de commandes finissant par un ;
sappelle instruction .

Notez bien que les prochains exemples seront souvent juste la procdure entre les
accolades de la fonction Main

1.5 Gestion de la mmoire vive en .NET
Pour comprendre un peu mieux certains phnomnes qui seront abords plus tard, nous allons
expliquer rapidement la gestion de la mmoire par le .NET framework. La mmoire est un point
essentiel pour pouvoir faire de la logique. Retenir des rsultats intermdiaire pour les rutiliser ou
autres. Pour enregistrer temporairement une valeur lui donne un nom. Ce nom sera utilis comme
un lien vers un espace mmoire. Cette association nom, espace mmoire et donne contenue est un
tout que lon appelle variable. Dans certains langages de programmation comme le C, le C++ ou le C#
nous avons des variables liens . Ces variables contiennent ladresse dune donne qui
ventuellement pourrait ne pas tre nomme. Ces variables liens sont en ralit appeles pointeurs,
elles sont souvent caches dans le .NET bien quelles soient utilises au cur du framework.

.NET spare la mmoire en deux parties isoles, la pile et le tas. Quand on fait un programme
en .NET, le framework nous rserve un espace mmoire. Les autres programmes ne peuvent
normalement pas y accder. Les donnes dites type valeur sont celles qui ont leurs valeurs dans
la pile. Les variables de type valeur sont le plus souvent inferieure 32 octets. Bien que performant
pour les petites variables le type valeur est complt par un autre type : le type rfrence. Les
variables de type rfrence ont un pointeur enregistr dans la pile qui pointe vers les donnes de la
variable. Ces donnes sont dans la zone mmoire appele le tas.

Un outil appel Garbage Collector est charg de librer et dfragmenter dynamiquement la
mmoire du tas. Ainsi, si des donnes nont plus de pointeurs associes, la mmoire est libre. Si les
donnes taient au milieu du tas, lespace libr sera rutilis par les donnes du fond du tas . Ce
procd permet de redimensionner notre espace mmoire rserv et donc de librer de la mmoire
pour le systme et les autres processus.
2 La syntaxe procdurale : logique C/C++ applique en C#
Comme nous le disions, la syntaxe du C# est trs inspire du C/C++, on peut mme faire de
larithmtique de pointeurs pour peu que lon dfinisse notre code en tant que Unsafe . Les
personnes ayant de bonnes bases en C/C++ ne verront rien dextraordinaire dans cette partie qui
risque de paraitre dense pour ceux qui partent de zro.

Remarque : Si cest votre tout premier cours de programmation, ce chapitre va vous paraitre dense, je
vous encourage essayer chaque exemple et essayer de prendre du recul avec cette partie dans votre
bagage pour mieux revenir sur la partie traitant de lorient objet.




1er avril 2008
6 C# : Lessentiel en concentr
2.1 Variables, oprateurs numrique et types.
Les oprateurs numriques sont la base des calculs et de la logique. La mmoire est un point
clef de la programmation. Pour interprter le code binaire dans une variable et donc la donne en
mmoire il faut en connaitre le type. La dclaration des variables, lattribution de leurs valeurs et les
oprateurs numriques de base sont similaire en C# et en C/C++, voyons comment les utiliser.

Dans une qute de synthse, jai fait peu dexemple dans cette partie, si vous trouvez dur
comprendre les types ou les oprateurs trop dtachez de la pratique avancez avec en parallle
lexemple en 2.1.3. Tous les oprateurs et tous les types ny sont pas illustrs. Durant lensemble du
cours vous verrez lusage de chaque operateur au moins une fois, mais pour ce qui est des types
jutiliserai principalement des entiers.

2.1.1 Les types
Voici quelques types de base utilisable en C#. Les types prsents dans ce tableau
lexception de string et les structures sont les seuls types tre stockes par valeur.

Classe Alias Octets Valeur codes
System.SByte sbyte 1 -128 127
System.Byte byte 1 0 255
System.Int16 short 2 -32768 32767
System.Int32 int 4 -2147483648 2147483647
System.Uint32 uint 4 0 4294967295
System.Int64 long 8 -9223372036854775808 9223372036854775807
System.Single float 4 -3,4
E
+38 3,4
E
+38
System.Double double 8 -1,79
E
+308 1,79
E
+308
System.Decimal decimal 16 -7,9
E
+29 7,9
E
+29
System.Char char 2 Caractre Unicode (UTF-16)
System.Boolean bool 4 Valeur true ou false
System.String string * Chane de caractres

Remarque : Ce tableau est adapt dun tableau que vous trouverez dans le chapitre 1 des cours sur
le Framework, ce chapitre pourrait vous aider approfondir vos connaissances techniques des bases
du typage, de lorient objet et vous y trouverez une explication plus dtaille et plus image de
lusage de la mmoire vive en .NET.

Contrairement certains langages (comme le python) tout objet doit tre explicitement typ.
Chaque variable a un type dfini et on est oblig de spcifier un type pour chaque argument de
chaque mthode. Pour allouer de la mmoire une variable, on cre une instruction avec dune part
le type et dautre part le nom de la variable. Si vous voulez trouver facilement la valeur maximale et
la valeur minimale dun type numrique, faites System.Int32.MaxValue pour retourner le plus
grand des int ou MinValue pour trouver le plus petit. Vous navez pas encore vu comment faire usage
de ses valeurs mais notez que les valeurs limites sont accessible dans le framework et de ce fait vous
ntes pas tenu de les retenir.

Si on ajoute une variables .GetType() , cela retournent le type de la variable. Vous verrez
un contrle de type utilisant cette mthode dans la partie sur la gestion des erreurs.





1er avril 2008
7 C# : Lessentiel en concentr
2.1.2 Les oprateurs
Pour traiter la variable on utilise des oprateurs. Voici les oprateurs dans leur ordre de
priorit (on pourra utiliser des parenthses pour redfinir les priorits comme en mathmatique.) :

Oprateur C# Signification
Calculs Ces oprateurs permettent de faire des calculs
* Multiplication.
/ Division.
% Modulo.
+ Addition.
- Soustraction.
Tests Ces oprateurs permettent de retourner des boolens (vrai ou faux)
is Teste le type dun objet (utilis parti 2.5)
< Inferieur .
> Suprieur .
<=,>= Inferieur ou gal, suprieur ou gal.
!= Diffrent de.
== Est gal
Logique Ces oprateurs traitent des variables et en retournent une.
&& ET logique (vrai si tous les membres sont vrai)
|| OU logique (vrai si au moins un des membres est vrai)
?? Retourne loprande de gauche si non-null ou bien celui de droite. (2.1.3)
cond ? var1 : var2 Renvoie var1 si cond est vrai ou alors var2 (Voir partie 2.2)
Attribution Ces oprateurs permettent dattribuer une valeur une variable
= Attribution (permet de donner une valeur une variable).
+=, -=,*=,/=,%=,&=,|= Permet de contracter la variable de loprateur et de lattribution *.
Incrmentation ** Ces oprateurs rattribuent une variable sa valeur modifie.
++ Ajoute 1 la valeur.
-- Enlve 1 la valeur.

* : Ces oprateurs dattributions ne servent qu faire une contraction pratique. Avec loprateur +=
on ajoutera la valeur actuelle de la variable la valeur attribuer. Variable <oprateur>= 12
quivaut Variable = Variable<oprateur>12. Vous aurez des exemples dans lextrait de code suivant.

** : Les oprateurs dincrmentation se placent sur une variable dans une instruction seule ou dans
un calcul. Si le signe est gauche de la variable ce sera excut en priorit absolue dans linstruction,
sil est droite la variable on incrmentera la toute fin de linstruction.

Remarque : On ne peut pas avoir plus dun oprateur dattribution par instruction.

2.1.3 Exemple de calculs et de dclaration de variable
Voici un exemple dutilisation :

C#

int a; // on dclare a de type int
int b = 5; // on dclare b et y attribu la valeur 5
a = 0; // on attribu la valeur 0 dans a

System.Console.WriteLine("a=\t"+a.ToString()+"\nb=\t" + b.ToString() + "\n");
/*****************************************************************************




1er avril 2008
8 C# : Lessentiel en concentr
* Toutes les variables objets ont la mthode ".ToString()".
* Applique un int, ".ToString()" retourne une chaine de
* texte contenant la valeur.
*
* L'oprateur "+" entre des string les concatnes c'est dire les fusione
* en les mettant la suite.
*
* "\n" et "\t" sont des caractres spciaux : voir partie 2.1.5
*****************************************************************************/
a += a + ++b; // b=b+1; a=a+a+b;
System.Console.WriteLine("a=\t"+a.ToString()+"\nb=\t" + b.ToString() + "\n");
a /= b; // a=a/b
a -= 2*b++*a; // a=a-2*b*a; b+=1;

System.Console.WriteLine("a=\t"+a.ToString()+"\nb=\t" + b.ToString() + "\n");
System.Console.ReadKey(); // attend que l'utilisateur appuie sur une touche

Retour Console:

a= 0
b= 5

a= 6
b= 6

a= -11
b= 7

Cet exemple peut paraitre court, cest vrais mais ne bloquez pas dessus, si ce nest pas acquis
maintenant, vous verrez des exemples partout dans ce court vu que cest vraiment la base. Il faut
retenir pour la dclaration des variables : le nom du type, le nom de la variable et le caractre de fin
dinstruction ( ; ). Lexemple montre que lon peut attribuer une valeur en mme temps que lon
dclare une variable (deuxime ligne).

2.1.4 Les chaines de caractres : quelques dtails
Dans le commentaire le plus imposant, on voit que pour les strings il existe des caractres
spciaux dont celui du retour la ligne et de la tabulation.
Voici quelques caractres spciaux :
\n, \r : retour la ligne
\t : tabulation (pratique pour les alignements verticaux)
\\ : permet dafficher un antislash
\" : permet dafficher un guillemet
\xXX ou XX est une valeur hexadcimale de deux caractres (chacun entre 0 et F) : permet
dafficher un caractre par son code hexa.

Si vous ne voulez pas bnficier du support de ces caractres et avoir une chaine non
interprte, il suffit de prcder la chaine par un @ (pratique pour les adresses de fichier par
exemple). Les chanes prcde dun arobase peuvent tre appeles chane Verbatim , ces
chanes peuvent contenir de rels retours la ligne.

Au lieu de concatner les chaines avec le signe + on peut ajouter des variables dans les strings
avec un moyen simple de formatage.

C#

int arg1 =12;
string arg2 = "bonjour";




1er avril 2008
9 C# : Lessentiel en concentr
ulong arg3 = 1546471534;
Console.WriteLine("arg1={0}\narg2={1}\narg3={2}",arg1,arg2,arg3);
arg2 = string.Format("{0}, {1}, {2}", arg1, arg2, arg3);
Console.WriteLine(arg2);
Console.ReadKey();
Retour Console

arg1=12
arg2=bonjour
arg3=1546471534
12,bonjour,1546471534

Cette mthode permet une visibilit un peu plus claire et peut viter un grand nombre de
.ToString() . Les arguments nattendent pas de type particulier.

2.1.5 Les valeurs clefs et les types nullable
Il existe des valeurs qui sont reprsentes seulement par des mots clefs. Ces mots clefs sont
null, true et false. Pour pouvoir attribuer la valeur null une variable (de type valeur) on utilise une
structure qui contient un boolen et la valeur de type dfini(le mot structure est dfini partie 2.4).
Ce boolen est appel HasValue. Lorsque sa valeur est true le nullable a une valeur, quand il est
false la variable vaut null.
Cet exemple vous montre les deux mthodes pour faire un nullable.

C#

uint? a = 2;
System.Nullable<uint> b = 15;
b = null;
a += b; // a = null + 2 cest dire a = null
b = 12;
System.Console.WriteLine(b.ToString()+"-*-"+a.ToString()+"-*-"+(a??b).ToString());
System.Console.ReadKey();
Retour Console

12-*--*-12

Si lon suffixe le type valeur dun ? on obtient ce type mais nullable. On peut aussi mettre
explicitement comme type de la variable nullable comme fait pour la variable b (Pour mieux
comprendre lutilit des chevrons qui dans se contexte ne veulent videment pas dire suprieur
, vous pourrez voir les classes gnriques dans le chapitre traitant de linstanciation). Ces variables
sont susceptibles de contenir null qui correspond nant , rien (dans certains cas dutilisation
non dfini ). Lintrt davoir une valeur null est le plus souvent pour mentionner que ce nest pas
dfini.

Lautre utilisation de null est la des-allocation de mmoire. Dans le cas ou la variable est de
type rfrence, si lui attribue null (exemple : variable = null ; ) ladresse stocke par le pointeur
dans la pile sera mise 0. Lorsque le Garbage Collector contrlera dans le tas la variable, vu que rien
ne pointe dessus elle sera supprime.

2.1.6 Le Cast
Le cast est un moyen dutiliser une variable qui nest pas du type utiliser pour le calcul. Cest
dire le cast permet de retourner une valeur du type attendu partir de la variable. Ainsi on pourra
par exemple caster un int en long pour utiliser une variable nayant pas les mme limites de
dpassement. Il y a deux moyens pour essayer de changer le type dun objet, un vite les erreurs
quand on nest pas sur que lobjet puisse tre cast et lautre retype ou renvoie une erreur ou une




1er avril 2008
10 C# : Lessentiel en concentr
valeur aberrante (pour comprendre quand on a une erreur ou une valeur aberrante regardez la
partie sur checked/unchecked).

Le mot clef as doit caster vers un type nullable ou rfrence (voir partie 2.7). Si la variable
est du type requis ou compatible , as retourne la valeur type. Au cas contraire il retournera null.
Le as est traduit avec dautres oprateurs dans lexemple. Pour rappel, loprateur ?? sert
retourner une autre valeur si le premier lment est null, il est parfois utilis avec as pour avoir un
retour en cas dimpossibilit de cast diffrent de null.

Le cast classique consiste imposer une variable de changer de type, si ce changement de
type ne fonctionne pas une exception est leve.

C#

int a = int.MaxValue;
long b = long.MaxValue;
long c = 15;

// cast implicite
object o = c;

// cast explicite necessaire
a = (int)b; //lve une overflowexeption si les dpassements sont contrls

// cast implicite
b = a; //fonctionne

// usage de as et de l'oprateur ??
b = (o as long?) ?? 0 ;
// quivau l'instruction:
b = ((o is long?) ? ((long?) o) : ((long?)null) ) ?? 0;
// l'oprateur ternaire sera dtaill dans la partie qui suit.
// ici, seuls "long" et "long?" fonctionnent pour le type de c

Console.WriteLine(b);
System.Console.ReadKey();
2.2 La condition: if else switch/case oprateur ternaire
Le mot clef if (en franais si ) permet lexcution conditionnelle de code. La condition
soumise if doit retourner un Booleen (True ou False), nous utiliserons souvent ici des oprateurs de
test. Ensuite nous passons la procdure excuter si la condition est vraie entre accolades.

Souvent, et cest vrai avec beaucoup de mots clefs, quand les accolades ne paraissent pas la
suite de la condition, le mot clef sappliquera uniquement sur linstruction qui suit.

Le mot clef else (sinon) est toujours prcd dau moins un if. else comme if est suivi de code
entre accolades. Ce code sera utilis seulement si la dernire instruction if na pas eu excuter le
bloc. Si lon doit procder une srie de test ou un seul doit tre excut, vous verrez une suite du
genre if, *else if, else if+, else , seule la procdure associe de la premire condition vraie sera
excute.

Le mot clef switch permet seulement de contrler diffrentes valeurs que peut prendre une
variable ou expression et dagir en fonction. Les propositions ne peuvent pas tre des variables, il ne
peut pas y en voir 2 identiques, tous les types de valeurs ne peuvent y tre utiliss et pour ce qui est
des performances le switch est la moins optimise des 3 solutions. Nanmoins certains dveloppeurs
trouvent sa syntaxe plus lisible et plus pratique que limbrication de if .





1er avril 2008
11 C# : Lessentiel en concentr
La syntaxe de loprateur ternaire est la suivante : (boolen) ? retourSiVrai : retourSiFaux .
On peut bien videmment en imbriquer plusieurs pour cumuler plusieurs conditions. Mais il faut
noter que loprateur ternaire permet un retour conditionnel et non pas une excution
conditionnelle, c'est--dire quil ne peut rien excut et quil se place dans des expressions comme
une valeur.

C#

int a;
string b;
System.Console.WriteLine("Entrez 2");
a = int.Parse(System.Console.ReadLine());
/* int.Parse prend le texte entr par lutilisateur (Readline())
* et en retourne la valeur indique si ce texte contien un nombre.
*/

// Mthode if/else
if (a == 2)
{
a = a; // a=a est une instruction inutile titre dexemple
b = "normal" ; // on peut mtre plusieurs instructions
}
else if (a == 1 || a == 3)
b = "Pas loin"; // on peut se passer dacollade pour une instruction seule

else // on aurai pu remplacer "else" par "if(a < 1 || a > 3 )"
{
b = "bizarre"; // une instruction seule passe mme avec les acollades
}
// Mthode switch/case
switch (a)
{
case 2: // le switch saute cette condition si a vaut 2
b = "Bien Jou !"; // puis excute ses instruction
break; // Le break fait sortir du switch
case 1: // en C# : pas de break = pas dinstructions
case 3: // le cas 1 vien excuter les instructions du cas 3
b="Pas loin";
break; // donc on sort du switch
default: // default reprsente tous les autres cas
b = "bizarre";
break;
}
// Mthode oprateur de retour conditionel
b= (a == 2) ? "normal" : (a == 1 || a == 3) ? "Pas loin" :"bizarre" ;

System.Console.WriteLine(b);
System.Console.ReadKey();

Cet extrait de code montre trois manires de faire la mme chose, Le programme demande
lutilisateur dentrer une valeur qui est affect dans a . A la fin on affiche la chaine de caractre
b . Entre trois faons pour mettre dans b :
la chaine Bien jou ! si a est gal 2
Pas loin si a est gal 1 ou 3
bizarre si a ne rpond aucun de ces critres.

Comme expliqu antrieurement, on constate que suite au if il y a une condition elle-
mme suivie dune ou plusieurs instructions. Dans le cas de lexemple ci-dessus si a est gal 2
a==2 retourne vrai ce qui engendre lexcution de laffectation de Bien jou ! . Lorsque lon




1er avril 2008
12 C# : Lessentiel en concentr
utilise le mot clef if juste aprs le else cest pour faire une liste de test, le premier vrai sera le seul
excut.

Le switch permet donc ici de tester les cas qui nous intressent individuellement c'est--dire
1, 2 et 3. Vu que le cas 1 et le cas 3 ont le mme traitement on peu les runir. Le mot clef break doit
tre mis en fin dexcution avant la nouvelle valeur du switch. Si vous voulez plus de renseignement
sur le switch ou en cas de problmes avec ce mot clef ou si vous voulez voir les diffrences entre le
switch C et le switch C#, je vous recommande cet article francophone.

Imbriqu, loprateur ternaire nest pas un cadeau pour ce qui est de la lisibilit. Pour rendre
plus clair lil, nous aurions pu mettre des parenthses autour de la sous expression ternaire ou la
mettre la ligne. Vous avez nanmoins pu constater laspect pratique de cet oprateur qui est celui
qui a eu la syntaxe la plus rapide, a naurai pas t pour lexemple, jaurai certainement mis
lexpression directement en argument de la mthode WriteLine sans passer par b . Bien quil
puisse paraitre pratique et assez optimis pour ce qui est des performances, loprateur ternaire va
par son manque de lisibilit lencontre des principes des langages rcents qui visent le confort de
dveloppement et la lisibilit. Il sera principalement utilis en argument de fonction vu quon ne peut
pas vraiment y mettre des excutions conditionnelles.
2.3 Les boucles: while do for goto
Les boucles font parti des fondamentaux de la logique de la programmation, notre prochain
exemple ressemblera enfin quelque chose vu que lon aura vu aprs a lessentiel de la partie
structure logique des instructions dans une procdure.

2.3.1 While
While (en franais tant que ) permet de faire une boucle conditionnelle, probablement le
type de boucle que vous croiserez le plus avec les boucles for. Niveau structure il ressemble au if, il a
une condition entre parenthses et un block de code ncessairement entre accolade pour peu quil
ait plusieurs instructions. Si la condition du while est vraie le block de code est excut, la fin de
cette excution, le block est excut nouveau si la condition et vrai et ce jusqu ce que ce ne soit
plus le cas.

C#

int a=2;
int b=15;
int temp;
while (b > 0)
{
if (a == 1)
a = 2;
else a = 1;
System.Console.WriteLine("Tour du joueur "+a.ToString()
+"\nil reste "+b.ToString()
+" allumettes\nprenez un nombre d'allumettes entre 1 et 3 (defaut 3)");
temp = int.Parse(System.Console.ReadLine());
if (temp > 0 && temp < 4)
b-=temp;
else b-= 3;
}
System.Console.WriteLine("joueur "+a.ToString()+" a perdu");
System.Console.ReadKey();

On peut voir dans cet exemple que tant quil reste des allumettes, les joueurs peuvent en
prendre jusqu ce quil y en ait plus moment ou on sortira de la boucle pour afficher le nom du




1er avril 2008
13 C# : Lessentiel en concentr
perdant. Le fonctionnement est simple et commun aux autres. Il suffit de maitriser un type de boucle
pour facilement comprendre les autres.

2.3.2 Do while
Trs similaire au while normal, il impose un minimum dune excution avant de contrler les
conditions de maintien de la boucle.

C#

int a=0;
do
{
System.Console.WriteLine(a++.ToString());
} while (a > 0 && a < 12) ;
System.Console.ReadKey();

Le do-while est lquivalent du while mais la syntaxe et diffrente et le contrle de condition
se fait la fin de la boucle. De ce fait le block est excut au moins une fois mme si la condition est
fausse en premier lieu. Dans ce cas a = 0, il excute le bloc une premire fois alors que la
condition est fausse. Ensuite jusqu ce que a ne respecte plus la condition il lincrmente et
laffiche. (Affiche les nombres de 0 11 inclus).

2.3.3 For
La boucle for est souvent trs pratique mais nest pas toujours aime des dbutants, cest un
while avec deux champs supplmentaires : une variable locale et une excution. Le tout est dans les
parenthses du for, nous y verrons ncessairement deux ; pour sparer les 3 champs. Refaisons
lexemple du jeu des allumettes avec une boucle for :

C#

int a = 2;
int temp;
for (int b = 15; b > 0; b-=(temp>0 && temp<4)?temp:3 )
{
if (a == 1)
a = 2;
else a = 1;
System.Console.WriteLine("Tour du joueur " + a.ToString()
+ "\nil reste " + b.ToString()
+ " alumettes\nprenez un nombre d'allumettes entre 1 et 3 (defaut 3)");
temp = int.Parse(System.Console.ReadLine());
}
System.Console.WriteLine("joueur " + a.ToString() + " a perdu");
System.Console.ReadKey();

La boucle for comme vous pouvez le constater met en valeur une variable locale qui sera le
plus souvent utilise dans la condition de la boucle (donc son instanciation), la condition mme puis
une instruction qui met en valeur le traitement fait chaque itration (a part la premire), vous
verrez souvent for(int a = 1 ; a<=10 ;a++){ //instructions ;} pour les boucles qui doivent se rpter
10 fois.

2.3.4 Goto
Le goto est une alternative bien qu viter qui permet des choses assez tonnantes. Le goto
fait un saut jusqu un endroit nomm n importe o dans la procdure. Pour nommer un endroit on




1er avril 2008
14 C# : Lessentiel en concentr
parle de label ou dtiquette, on met son nom suivi de : . Jai mis la mthode Main dans cet
exemple pour montrer que par convention, ces labels sont indents en retrait sur la gauche. La
condition boucle ralis avec if. Dans ce contexte le goto et le label sont proscrire du fait quun do
while permet la mme chose. Il est important de noter que le goto peut aussi faire un saut vers un
label qui est en aval dans le code ce qui peut permettre de sortir par exemple dune imbrication de
boucles.

C#

static void Main()
{
int a = 2;
int temp=0;
int b = 15;

nouveauTour:
if (a == 1)
a = 2;
else a = 1;
System.Console.WriteLine("Tour du joueur " + a.ToString()
+ "\nil reste " + b.ToString()
+ " alumettes\nprenez un nombre d'allumettes entre 1 et 3 (defaut 3)");
temp = int.Parse(System.Console.ReadLine());
if (temp > 0 && temp < 4)
b -= temp;
else b -= 3;
if (b > 0)
goto nouveauTour;

System.Console.WriteLine("joueur " + a.ToString() + " a perdu");
System.Console.ReadKey();
}

Remarque : Le goto est mal aim de beaucoup de programmeurs car goto ne respecte pas la
structure logique de la pense de de lindentation et du coup cest moins lisible que les autres boucles.
Certains programeurs vont jusqu interdire lutilisation du goto ou dvelopper des langages
nimplmentant pas ce type de boucle. De ce fait dans la mesure du possible il faut privilgier
lutilfisation dautres types de boucles.

2.3.5 Sortie de boucles : Break-Continue
Il peut arriver dans le cas ou les boucles effectuent plusieurs oprations que lon veuille sortir
directement de la boucle ou sauter lexcution de la fin du block, pour a il existe les mots clefs break
et continue. Le mot clef break permet de sortir brutalement de la boucle tandis que continue renvoie
au test. Il va sans dire que ces deux instructions ne fonctionnent pas dans le cas de boucle faites au
goto.

C#

int a = 2;
int temp=0;
int b = 15;
while(true)
{
if (a == 1)
a = 2;
else a = 1;
System.Console.WriteLine("Tour du joueur " + a.ToString()
+ "\nil reste " + b.ToString()
+ " alumettes\nprenez un nombre d'allumettes entre 1 et 3 (defaut 3)");
temp = int.Parse(System.Console.ReadLine());




1er avril 2008
15 C# : Lessentiel en concentr
if (temp > 0 && temp < 4)
b -= temp;
else b -= 3;
if (b > 0) continue;
break;
}
System.Console.WriteLine("joueur " + a.ToString() + " a perdu");
System.Console.ReadKey();

Evidemment ce cas est plus un cas dtude quun cas pratique, vous aurez un autre exemple
aussi explicite mais montrant plus lintrt de ces mots clefs dans la partie sur la gestion des erreurs.

2.4 Array enum struct
Pour grouper des variables ou des valeurs il y a plusieurs outils, les trois outils que je vous
prsente ici sont trs diffrents.
Struct : dfini un type de variable plusieurs champs.
Enum : organise des valeurs clefs
Les arrays sont des variables dclares en tant que liste de valeurs de type commun.

Lexemple propose un semblant dorganiseur de tches et fait la somme de la dure des
vnements de la semaine. enum et struct sont pour faire des dclarations qui seront en dehors de
Main.

enum et struct forment des lments, une fois dfinis on ne peut plus les modifier. Dans la
structure (struct) on dfinie chacune de ses sous variables et leur types comme si on dclarait des
variables. Vous remarquerez le mot public . La structure est en ralit trs proche de la classe
(voir chapitre 1 sur le framework) mais nest en gnral utilis que pour ranger un petit nombre de
variable.

C#

class truc
{
struct evenement
{
public int[] jours;
public string tache;
public int duree;
}
enum semaine
{lundi=1, mardi, mercredi, jeudi, vendredi, samedi, dimanche}
enum longueurTemps
{tresCourt=15,court=30,moyen=60,assezlong=90,deuxheures=120,treslong=240}

static void Main()
{
int temp=0;
evenement[] cal = new evenement[]
{
// La syntaxe utilise ci-dessous pour remplir les vnements = C#3.0
new evenement{
jours= new int[] {(int)semaine.dimanche,(int)semaine.mercredi},
tache="faire la vaiselle",
duree=(int)longueurTemps.court},
new evenement{
jours=new int[7],
tache="lire ses flux RSS",
duree=(int)longueurTemps.assezlong},
new evenement{




1er avril 2008
16 C# : Lessentiel en concentr
jours = new int[] {(int)semaine.lundi, (int)semaine.mercredi},
tache = "prendre un bain",
duree = (int)longueurTemps.moyen}
};

cal[1].tache += " et suivre quelques liens";

for (int i=0; i < cal.Length; i++)
{
temp += cal[i].duree * cal[i].jours.Length;
System.Console.WriteLine(((double)temp/60).ToString()+
" heures de ta semaine occupe (tche ajout: " + cal[i].tache+" )");
}
System.Console.ReadKey();
}
}

Retour Console:

1 heures de ta semaine occupe (tche ajout: faire la vaiselle )
11,5 heures de ta semaine occupe (tche ajout: lire ses flux RSS et suivre
quelques liens )
13,5 heures de ta semaine occupe (tche ajout: prendre un bain )

Les principaux points retenir ici sont :
Lorsque lon appelle lenum il faut caster pour avoir le type dsir
Les arrays sont taille statique, vous ne pourrez pas ajouter dlments, pour faire des sortes
d arrays dynamique on utilisera une classe gnrique (voqu dans le chapitre 3.7 sur
linstanciation).

2.4.1 foreach
Vous avez constat que ma boucle for me permettait de parcourir la liste cal avec la
variable i qui me sert dindex. De ce fait je traite tour tour chaque lment de larray. Pour faire
cette dmarche plus lisiblement et gagner en taille de code jaurai pu refaire ma boucle comme suit :

C#

foreach (evenement e in cal)
{
temp += e.duree * e.jours.Length;
System.Console.WriteLine(((double)temp/60).ToString()+
" heures de ta semaine occupe (tche ajout: " + e.tache+"
)"+semaine.lundi.GetType());
}
System.Console.ReadKey();

La liste cal est la mme que dans lexemple prcdent, on fait passer tour tour dans la
variable locale chaque lment e. Au final on excute les mmes instructions quavec la boucle for
dans lexemple antrieur. Notez le mot clef in qui napparait que dans ce contexte. Pour quun
foreach soit utilisable sur un objet ce dernier doit avoir un comportement adquat (voir la partie sur
les itrateurs).

2.5 Gestion des erreurs : try-catch finally
Comme vous lavez peut tre dj constat, si vous entrez une chose qui nest pas assimilable
du texte dans le jeu qui nous sert dexemple, nous avons une erreur. Pour grer les erreurs nous
pouvons isoler le code propice lerreur et lisoler dans un bloc de code try . Nous pouvons
regarder la documentation de la mthode propice lerreur pour voir les diffrents types derreurs




1er avril 2008
17 C# : Lessentiel en concentr
qui peuvent advenir en ce contexte. La mthode propice lerreur dans notre code est Parse , la
surcharge prenant en argument un string : les exceptions de Parse(string) sur MSDN. Pour pouvoir
traiter lerreur, on va ranger le code en cas derreur dans un bloc catch . Si on met catch seul (sans
arguments ni parenthses) le traitement sera le mme quelque soit lerreur et on ne pourra pas
retourner dinformations relatives aux erreurs. En mettant les parenthses et un argument gnral
(comme dans notre exemple) on a une variable interne au catch ( e ) qui contiens les donnes de
lerreur et qui permet de es afficher et de ragir.

Les exceptions sont des classes qui seront dfini en exemple sur lhritage. Exception
regroupe toutes les catgories c'est--dire tous les types dexceptions. Dans notre exemple nous
comparerons les types de lexception ceux que lon a trouvs sur MSDN pour voir la comparaison
des types. Nous retraiterons les erreurs dans la partie Exemple dhritage .

Le mot clef finally le plus souvent utilis pour librer la mmoire est plac aprs le try et le
catch. Ce block sera excut quil y ait erreur ou non.

Remarque: voici quelques principaux attributs communs toutes les Exceptions permettant dobtenir
des informations pour signaler, trouver et corriger les bugs :
Message est un String dcrivant la cause de lerreur de manire relativement explicite pour
un utilisateur.
HelpLink retourne ladresse (ex :URL) du fichier daide associ au type de lexception.
Source donne le nom de la rfrence, lassembly ou du fichier source qui est lorigine.
TargetSite permet davoir le type de retour de la mthode qui lev lerreur et le type des
arguments.
StackTrace donne la ligne de lerreur et remonte du Main la mthode qui lve lexception et
fourni la ligne.

C#

uint a = 2;
uint temp = 0;
uint b = 15;

while (b > 0)
{
if (a == 1)
a = 2;
else a = 1;
System.Console.WriteLine("Tour du joueur " + a.ToString()
+ "\nil reste " + b.ToString()
+ " alumettes\nprenez un nombre d'allumettes entre 1 et 3\n(defaut 3,
nombre ngatif pour abandoner)");
try
{
temp = uint.Parse(System.Console.ReadLine());
}
catch (System.Exception e)
{
System.Console.WriteLine(e.Message);
if (e.GetType().Equals(typeof(System.ArgumentNullException)))
System.Console.WriteLine("impossible: retour minimal= \"\" (non-
null)");
else if (e is System.OverflowException)
break;
else System.Console.WriteLine("message non parsable");

if (a == 1) a = 2;
else a = 1;
continue;




1er avril 2008
18 C# : Lessentiel en concentr
}
if (temp < 4)
b -= temp;
else b -= 3;
}

System.Console.WriteLine("joueur " + a.ToString() + " a perdu");
System.Console.ReadKey() ;


Remarque : typeof est un mot clef qui prend en argument une classe et qui retourne un type, ici il
nous permet de savoir si le type de lerreur e relve bien des classes en argument.

2.6 Instructions prprocesseurs
Je ne mettrai pas dexemple pour linstruction prprocesseur, cest assez peu utilis bien que
ce soit la seule manire pour pouvoir dfinir des instructions compilation conditionnelle. En gnral
ce ne sera pas utilis, dautan que contrairement au C/C++ classique, #define ne permet pas de
faire de macros. Une liste des mots clefs des instructions prprocesseurs est disponible cette page :

http://msdn.microsoft.com/fr-fr/library/ed8yd1ha(VS.80).aspx

2.7 Le code unsafe et checked / unchecked
Cette partie aura du sens particulirement pour ceux qui ont dj manipul des pointeurs en
C/C++, bien que cela permettes des choses assez puissante, on peu parfaitement se passer de ce
mode part pour le hacking. Le mode unsafe (pourrait tre traduit par non sr) permet de manipuler
directement les adresses mmoire et donc les pointeurs. Nous allons voquer ici quelques mots
clefs : unsafe, stackalloc, fixed.

Pour pouvoir compiler du code unsafe, vous devez le spcifier, depuis Visual Studio
slectionnez : projet > proprits du projet, vous devrez cocher une checkbox dans longlet gnrer
(projet>options>Options du compilateur pour MonoDevelop ou le paramtre de commande /unsafe
dans le terminal) pour spcifier explicitement votre autorisation.
Ces dplacements de donnes tant gnants si lon utilise des adresses mmoire, on a deux
moyens de solutionner le problme : stackallock (rappelle un peu le malloc) qui permet dallouer de
la mmoire dans la pile et fixed qui empche au garbage collector de dplacer certaines donnes du
tas.

Illustrons par un exemple utilisant les pointeurs :
C#

unsafe static void Main()
{
int* variable = stackalloc int[100];
// stackalloc ne s'utilise que pour des arrays types valeur
for (int i = 0; i < 100; i++)
{
*variable++ = i;
Console.WriteLine( (int)variable );
}
variable-=100;
for (int i = 0; i < 100; i++)
System.Console.WriteLine(*variable++);






1er avril 2008
19 C# : Lessentiel en concentr
char[] texte = new char[] {'t','a','m','t','l','e','m','o','u','s','s','e'};
fixed (char* pointeur = &texte[0])
{
pointeur[3] = 'p';
*pointeur = pointeur[3];
for (int i = 0; i <= texte.Length; i++)
System.Console.Write(pointeur[i]);
}
System.Console.ReadKey();
}

int* est un type de donne pointeur. Cest un pointeur ver un objet de type int.
*variable correspond au contenu de la variable. Cest la donne proprement parle.
variable correspond ladresse mmoire de la variable.
&variable correspond ladresse mmoire de la variable.

Stackalloc est lquivalent de _alloca de la bibliothque runtime C, il a allou 400 octets et
retourn un pointeur. Derrire on peut manipuler le pointeur comme en C. fixed permet de faire un
pointeur fixe, la variable pointeur ne peut tre modifi ni par notre code ni par le Garage
Collector. Unsafe dfini des blocks de code, il peut tre mis seul avant un block comme try (unsafe{
/*instructions*/ }) ou il peut sajouter aux spcifications dun block existant comme dans lexemple.
Le code mis en unchecked (un calcul ou un block) est un peut plus performant mais les
rsultats peuvent changer, unchecked consiste ne plus contrler les dpassements de valeurs. De
ce fait le comportement est de retourner la valeur minimale quand on est trop grand et
inversement. (Application des oprations binaire avec mise lcart des retenues). Par dfaut avec
Visual Studio tous les codes sont en unchecked, de ce fait, pour que ces blocks aient vraiment un
sens, il faut avoir le contrle de dpassement (checkbox dans projet>proprit du
projet>gnrer>options avances dans Visual Studio ou sous MonoDevelop dans
projet>options>configuration>debug>Options du compilateur ).


C#

int var;
unchecked
{
var = int.MaxValue;
var *= 2;
System.Console.WriteLine("\n" +var.ToString() + "\n" + ((int)(int.MaxValue
+1)).ToString());
}
System.Console.ReadKey();
Retour Console:

-2
-2147483648

Si vous navez pas dans les options du compilateur le contrle de dpassement de coch par contre
vous pouvez lactiver sur un calcul ou un block avec le mot clef checked .

C#

int a = int.MaxValue;
int b = 12;
b=checked(a * b); // ce code gnrera ici une erreur de type OverflowExeption .
Console.WriteLine(b);




1er avril 2008
20 C# : Lessentiel en concentr
3 Lorient Objet en C#
3.1 Introduction
Comme nous le disions dans lintroduction, lorient objet est un moyen de regrouper des
variable pour pouvoir traiter des ensemble comme des entits propres. C# est un langage fortement
orient objet. Les objets correspondants quelque chose, il faut les dfinir avant den utiliser. Par
chance le framework .NET propose dj une belle liste dobjets. La dfinition est appele la classe
et la variable contenant lobjet est appeles linstance. Avant de samuser instancier nimporte quoi
nous allons voir comment on cre des classes simples (qui rangent des variables), nous verrons
ensuite comment utiliser ces classes..

3.2 Using
Dans la partie 2 vous avez certainement trouv que lon utilisait beaucoup System. . System
est un NameSpace que lon peut aussi appeler espace de nom . Les NameSpaces servent ranger
les classes un peu comme dans des dossiers. Si lon veut sconomiser dcrire System chaque fois
que lon veut accder un objet de ce NameSpace, il suffit de mettre au dbut du fichier using
System ; . Ces imports despaces de nom permettent daccder directement tous les lments
contenus (appart les NameSpaces quil contient) sans avoir mentionn ou il est rang. Plus vous
ferrez de using plus vous aurez de propositions lauto compltion, do lintrt de limiter lusage
des using car cela permet une auto compltion plus rapide et plus pertinente.

3.3 Instanciation
Nous allons dfinir des classes mais pour savoir comment on les instancie nous allons dabord
regarder cette classe intgre dans le Framework que nous avons dj utilise avec une instanciation
simple : le String

C#

System.String var= new System.String(new char[] {'l','e','t','t','r','e'});

Dcomposons cette instruction. Nous avons dans un premier temps le type et le nom de la
variable pour la dclaration. En suite nous avons le mot clef new, on utilise nouveau le type que
lon appelle comme une fonction. Cette notion de fonction et dargument la dclaration seront
expliqus dans la partie 3.8.2. Nous attendons aussi un argument. Dans cet exemple largument est
un Array de char, comme on compte en mettre un qui nexiste pas, qui nest pas dclar, bref un
nouveau comme pour le String on met le mot clef new et on met de la donne.

Remarque : les classes anonymes sont une nouveaut de C# 3.0, si vous dveloppez sur un logiciel
existant, il vous faudra spcifier de compiler avec la syntaxe C# 3.0 pour pouvoir faire ce qui vas
suivre. Le code C#2.0 compilera normalement en C#3.0 sans modifications.

Parfois on doit crer une classe pour ranger des variables, mais pour une utilisation locale et
qui ne sortira pas de la mthode en court. Dans ce cas il existe une syntaxe de dclaration de classe
prcise qui gnre des Classes anonymes . Les classes anonymes ont un nom de classe gnr la
vole sans informer le dveloppeur de ce fait on ne peut pas spcifier explicitement le type de la
variable qui vas contenir cette classe. Pour dclarer une variable dont on ne connait pas le type, il
existe un mot clef appropri : var . Le mot clef var permet de laisser le compilateur typer la
variable notre place. Une classe anonyme se remplie un peu comme un array, exemple :

C#




1er avril 2008
21 C# : Lessentiel en concentr

var classeanonyme = new { a=1, b=12,
c="texte",
d= "quelquechose"};
Console.WriteLine(classeanonyme.b.ToString()+classeanonyme.c);

Comme dit prcdemment, le framework est un ensemble de classes organises dans des
espaces de noms, pour linstant nous avons uniquement utilis des lments de System. Je vais vous
prsenter des objets de System.Collection.Generic. Ce NameSpace contient de quoi faire des listes
dynamiques et de type de votre choix, ce type doit tre nomm. Le type des lments contenus dans
la liste doit correspondre au type entre les chevrons.

C#

public List<int> liste = new List<int>();
liste.Add(12);

Ce type de liste vous permet de ranger, ajouter, enlever, modifier, trier et chercher les
lments. Vous pourrez utiliser ces listes pour ranger des objets de mme type ou de type de mme
forme. De ce fait pour faire des listes de types anonyme, bien quil y ait des astuces, que ce soit
dcompiler les assemblies pour connaitre le nom de la classe anonyme ou autre elles savrent
relever de la bidouille et ne sont pas explicites la lecture du code.

3.3.1 Lattribut et le modificateur daccs
On a dfini le modle objet comme un moyen conceptuel pour organiser des variables et les
traiter par groupe. Certaine variables internes aux objets ne requirent pas dinteractions depuis
dautres parties applicatives. Des accs plus restreints entrainent plus de facilit pour reprer les
erreurs, en rduire le nombre, une auto compltion plus pertinente, plus de facilit si quelquun doit
utiliser la classe et de cibler la documentation sur les variables, mthodes et proprits accessibles.

Les attributs dans les classes comme dans les structures doivent avoir de dfini un degr daccs.
Ces niveaux daccs sont dfinis par un de ces quatre mots clefs:
Public : donne tout laccs toutes les mthodes de toutes les classes.
Private : Restreint laccs la classe mme, il sera souvent prfrable dutiliser Protected.
Protected : Comme Private, la diffrence tant mince elle sera explique dans la partie sur
lhritage.
Internal : internal retire laccs toutes les mthodes et tous les lments qui ne partagent
pas la mme assembly (qui ne font pas parti du mme fichier compil).

Ces modificateurs sont communs pour les classes, les mthodes, les attributs, les accesseurs,
cest donc important connaitre et vous aller les croiser souvent (surtout les trois premiers).

Lattribut est donc la variable simple dans la classe, vous en avez dj vus dans la structure.
Refaisons en Partial une petite dclaration dattribut que lon va instancier.

C# : fichier 2

using System;

namespace ConsoleApplication
{
partial class Class
{
public int a =12;
public const ulong constante = (ulong) 128;




1er avril 2008
22 C# : Lessentiel en concentr
}
}

C# : fichier 1

using System;
using System.Collections.Generic;
namespace ConsoleApplication
{
partial class Class
{
public string b = constante.ToString();
public List<int> liste = new List<int>();
}
static class Program
{
static void Main()
{
Class var = new Class();
var.liste.Add(var.a);
var.b += " " + var.liste[0].ToString();

Console.WriteLine(var.b);
Console.ReadKey();
}
}
}

La variable dclare avec le mot clef const doit tre attribue dans la mme instruction et
ne pourra plus tre modifie. On verra dautres moyens qui peuvent paraitre plus pratique pour
limiter en criture les variables.

3.4 La proprit
Lorsque lon a des variables assimiles des objets, elles peuvent avoir des contraintes autres
que les contraintes informatiques, pour viter quune variable enfreigne ces contraintes, on peut en
dfinir lattribution. De plus, on peut vouloir contrler laccs en lecture de certaines variables ou
mme les mettre dans un format plus propice que celui du fonctionnement interne lobjet.
Voici un exemple de code, notez bien les mots clefs get , set et value .

C#

class Class
{
protected uint _var = 0 ;
public uint a
{ get
{ return _var+1; }
set
{ if (value < 100)
_var = value;
else
_var = 100; }
}
}
class Program
{
static void Main()
{
Class objet = new Class();
for (int i=0; i < 120; i++)
{
objet.a = i;




1er avril 2008
23 C# : Lessentiel en concentr
Console.WriteLine(objet.a);
}
Console.ReadKey();
}
}

Ainsi, quand on appelle lattribut a dun objet de classe Class , en ralit on accde
_var. Ce procd scurise lapplication du fait que _var soit en protected et du coup inaccessible
par du code ne venant pas de la classe. Dans notre exemple, on empche la variable de dpasser
100 en valeur interne, elle pourra retourner entre 1 et 101. On pourrait tout fait mettre plusieurs
instructions dans le get (qui correspond laccs en lecture de la variable spciale). On peut faire un
accesseur avec seulement get ou seulement set pour lavoir en lecture seule ou criture seule. Les
attributs ne sont pas forcment lis une variable interne, elle peut tout a fait manipuler plusieurs
ou aucune variable (dans ce dernier cas lintrt sera limit par rapport une mthode).
Comparativement au mot clef const qui empche toute criture, le couple variable
prive/get (sans set) permet de modifier en interne les valeurs.

3.5 Static
Normalement pour accder un attribut, une proprit ou une mthode, on doit forcment
crer un objet de la classe pour pouvoir lutiliser. Le mot clef static permet davoir des variables
et mthodes utilisable non pas dune instance mais de la classe elle-mme

C#

class Class
{
static protected int _var = 0 ;
static public int attribut
{
get
{
return _var+1;
}
set
{
if (value < 100)
_var = value;
else
_var = 100;
}
}
}
class Program
{
static void Main()
{
for (int i=0; i < 120; i++)
{
Class.attribut = i;
Console.WriteLine(Class.attribut);
}
Console.ReadKey();
}
}

Si je veux une classe qui serve de boite outils je peux crer des mthodes statiques qui ne
ncessitent pas que la classe soit instancie. Si on dclare la classe entire en statique, cela entraine
quon ne pourra pas en faire dinstances et quil ny aura pas de constructeur. Tous les lments
dune classe statique doivent tre spcifis en statique.




1er avril 2008
24 C# : Lessentiel en concentr

Remarque : Les classes statiques sont un moyen simple de faire un Singleton. Un singleton est un
objet qui ne peut tre instenci quune seule fois, ici la classe statique ne peut avoir quune
instance .

Dans le cas dune classe statique, il faudra utiliser private au lieu de protected, ce sera dtaill
dans la partie sur lhritage.

3.6 Les mthodes
Le mot fonction vous paraitrait certainement plus clair et cest pour a que jusqu ce point du
chapitre il marrivait de lemployer, mais les fonctions qui sont lis des objets ont une autre
appellation : ce sont des mthodes. Pour linstant nous navons vu que la mthode Main qui sera
trait et explique en premier lieu. Pour comprendre les mthodes il faut savoir quelles sont dfinies
par : un degr daccs, un nom, un type de retour et des types et un nombre (pouvant tre nul)
darguments. Cette dfinition est appele prototype ou signature et a une syntaxe
particulire. Dans cette partie essentielle sur les mthodes, nous allons :
commencer par expliquer la mthode Main, nous allons aussi voir comment passer
des paramtres lexcution, comment une mthode retourne une valeur Bref
lessentiel de ce que lon a comprendre sur les mthodes sera expliqu sur la
mthode Main que lon a beaucoup utilise sans vraiment lexpliquer.
Nous verrons ensuite comment crer une mthode qui permette de gnrer
proprement le contenu de la classe avec des arguments (les constructeurs).
Puis nous aborderons comment proposer plusieurs signatures avec la mme
mthode (la surcharge).
Comment entrer une mthode existante dans une variable
Comment faire des mini-mthodes pratiques en argument
Et enfin nous aborderons les Itrateurs.

3.6.1 Retour sur Main
Le C# est trs orient objet, du coup mme la mthode qui sexcute au dbut du
programme est range dans une classe. Comme on a dj beaucoup utilis Main regardons-le
directement pour pouvoir expliquer clairement les choses.

C#

class Program
{
static int Main(string[] args)
{
foreach (string s in args)
Console.WriteLine(s);
Console.ReadKey();
return 0;
}
}
Retour Console: excut manuellement : C:\adresse\application.exe avec des arguments

avec
des
arguments

Comme vous laurez remarqu, Main est Statique, cest tout bonnement car lorsque le
programme sexcute, la classe contenant Main nest pas instancie. Antrieurement, Main navait




1er avril 2008
25 C# : Lessentiel en concentr
pas dargument et la place de int il y avait le mot void. Le type spcial void que nous utilisions
sert dire que la mthode ne retourne rien. void est lallias de System.Void, il nest utilis que pour
mentionner que la mthode ne retourne pas de valeur et en unsafe pour faire pointeur vers donnes
de type inconnu. De ce fait, dans cet exemple, Main retourne une valeur : 0. Le mot clef return met
fin la mthode et lui fait retourner la valeur qui suit. Faire retourner une valeur de type int un
programme sert spcifier un code derreur. Par convention, le 0 signifie que tout cest bien
drouler, ensuite on peut crer plein de valeur de retour pour signaler les diffrentes erreurs
possibles. Usuellement, il est publi avec le logiciel une correspondance entre la valeur de retour en
cas derreur et les erreurs elles mmes.
Contrairement au C, une mthode devant retourner une valeur sans mot clef return ne passe
pas la compilation, de ce fait une mthode qui a un type de retour autre que void finira
systmatiquement par un return. Parfois pour les procdures, il peut tre plus pratique de faire un
return true quand il ny a pas de problme et false la place de lever une exception, on mettra bool
pour le type de retour.
Main a 4 Signatures possibles :

C#

public static int Main()
public static void Main()
public static int Main(string[] arg)
public static void Main(string[] arg)

LArray de string est compos de lensemble des chaines qui suivent la commande en
sparant par des espaces.
3.6.2 Constructeur / destructeur
Vous trouverez souvent dans les classes non statiques des mthodes dites constructeurs.
Ce sont des mthodes qui servent mettre des valeurs par dfaut, crer des lments Si on
voulait par exemple faire une classe qui range un jeu dallumette proche de celui que lon a fait
antrieurement :

C#

using System;
class Jeu
{
readonly public int nbreBatonets;// readonly = variable ne peut tre accde
readonly public int nbreJoueurs;// en criture que dans le constructeur.
protected int joueur;
protected int tour;
protected int batonets;
public string[] noms;
public static uint nbreDInstances;

/***************************************************
* Voici le Constructeur, cest une mthode spciale sans type de retour
* et qui porte le mme nom que la classe.
* On initialise ici les variable de Jeu propre aux options
***************************************************/
public Jeu(int nbreBnts, int nbreJrs,params string[] noms)
{
nbreDInstances++;
nbreJoueurs = nbreJrs;
nbreBatonets = nbreBnts;
this.noms = noms;
this.initGame();
}
// !! Le prochain extrait de code sera ajouter ici !! //
public void initGame() //Cette mthode permet dinitialiser une nouvelle partie




1er avril 2008
26 C# : Lessentiel en concentr
{
joueur = 0;
tour = 0;
batonets = nbreBatonets;
}
public bool Tour() //excute un tour et renvoie faux si dfaite.
{
int tmp;
tour++;
if (joueur < nbreJoueurs-1)
joueur ++;
else joueur = 0;
System.Console.WriteLine("Tour "+tour.ToString());
System.Console.WriteLine("A " + noms[joueur]
+ "\nil reste " + batonets.ToString()
+ " alumettes\nprenez un nombre d'allumettes entre 1 et 3 (defaut 3)");
int.TryParse(System.Console.ReadLine(),out tmp);
if (tmp > 0 && tmp < 3)
batonets -= tmp;
else batonets -= 3;
if (batonets < 1) return false;
return true;
}
// La mthode Perdu sera remplace dans la partie sur la redfinition
public string Perdu()
{
return noms[joueur]+" a perdu au bout de " +tour.ToString()+" Tours.";
}
~Jeu()
{
nbreDInstances--;
}
}

class Program
{
static void Main()
{
Jeu jeu = new Jeu(15,2,"Crovax","Popi");
while (jeu.Tour()); // excutera le test jusqu ce quil retourne faux
Console.WriteLine(jeu.Perdu());
/*
for (int i =0 ; i < 10000; i++)
{
Console.WriteLine(Jeu.nbreDInstances);
jeu = new Jeu(i, i, new string[] { "joueur1", "joueur2" });
System.Threading.Thread.Sleep(10);
}
*/
Console.ReadKey();
}
}

Remarque : Voil un extrait de code susceptible dclaircir lintrt du mot clef static. Si vous d-
commentez la boucle for et essayez plusieurs fois en modifiant quelques valeurs, vous pourrez
constater le fonctionnement du garbage collector.quand le garbage collector veut effacer un objet il
appelle de destructeur puis supprime les donnes de linstance qui ne lont pas t.

Un mot clef important na pas t abord : this. Il est ici employ pour viter un conflit de
noms. this correspond linstance en cours de traitement donc this.noms correspond la
proprit public quand noms seul correspond la valeur pass en argument de la mthode.

Le mot clef params est utilis ici dans le constructeur mais est optionnel et peut tre utilise
pour nimporte quelle mthode. Il est utilis pour le dernier argument, il est suivi dun type array et




1er avril 2008
27 C# : Lessentiel en concentr
dun nom de variable ( noms ). Tous les derniers arguments lappel de la mthode devront tre
des strings et rentrerons dans larray. Sans le mot clef params , linstanciation de la classe Jeu
naurait pas tait comme vu dans lextrait ( Jeu jeu = new Jeu(15,2,"Crovax","Popi"); ) mais
avec un vritable array en argument ( Jeu jeu = new Jeu(15,2,new string[]
{"Crovax","Popi"}); ). Params accepte aussi la syntaxe avec array en argument.
Nous utilisons le mot clef out dans la mthode statique TryParse dInt32, ce mot clef
apparait pour dire que largument passe par rfrence. C'est--dire que la variable pourra tre
modifie dans la mthode, car les types valeurs ne sont jamais modifies quand ils sont passs en
argument sans mots clefs spcifiant le contraire. Un mot clef trs proche de out existe : ref. La seule
diffrence est que lon utilise out pour une mthode qui vas donner une valeur sans tenir compte de
lactuelle tant disque ref sera plus utilis pour traiter une variable faire en sorte quelle ait une
nouvelle valeur partir de sa valeur actuelle. De ce fait, ref attend une variable ayant une valeur
attribue tandis que out une variable dclare mme sans attributions fera laffaire. De ce fait on
nest oblig de passer des variable et non pas des valeurs pour que la mthode puisse mettre ses
donnes quelque part. TryParse procde comme Parse sauf quil entre 0 dans la variable au lieu de
gnrer des erreurs. Les mots clefs param, ref et out paraissent dans les prototypes/signature des
mthodes qui les utilisent.

Le Destructeur na ni de type de retour ni de degrs daccs ni darguments. Son nom est
celui de la classe et est prcd dun tilde ~ .
3.6.3 La surcharge
Vous trouvez peut tre quil nest pas pratique de ne pas pouvoir faire un objet par dfaut,
davoir spcifier chaque fois tous les arguments Pour pouvoir avoir le choix entre plusieurs
possibilit darguments en entre il existe la surcharge des mthodes. Nous allons procder la
surcharge du constructeur. La surcharge dune mthode permet de changer la signature en gardant
le mme nom. Une surcharge permet de changer les paramtres et le type de retour.

La surcharge peut aussi sappliquer un oprateur comme le * , le / , il suffit de
prcder loprateur du mot clef operator. Du fait que ce soit vous qui dfinissiez lexcution vous
pouvez lutiliser avec la syntaxe et la priorit des oprateurs sans pour autan bien que ce soit
recommand faire une excution qui correspond une addition ou qui retourne une valeur.

On peut aussi surcharger loprateur unaire de cast, il y a deux types de dfinition de cast :
implicit et explicit. La surcharge peut tre dclare dans la classe dinstance source pour aller vers un
type cible ou dans la classe cible source de type quelconque et retourne un objet de classe. Pour
amliorer la lisibilit du code il est encourag dutiliser explicit dont le comportement est plus
prvisible.

C#

class Jeu
{

public Jeu()
{
nbreDInstances++;
nbreJoueurs = 2;
nbreBatonets = 15;
this.noms = new string[] {"Crovax","Popi"};
this.initGame();
}

public static Jeu operator+(Jeu un,Jeu deux)




1er avril 2008
28 C# : Lessentiel en concentr
{
string[] noms=new string[un.noms.Length+deux.noms.Length];
int p =0;
for (int i=0 ; i<un.noms.Length;i++)
noms[p++]=un.noms[i];
for (int i=0 ; i<deux.noms.Length;i++)
noms[p++]=deux.noms[i];

return new Jeu(un.nbreBatonets + deux.nbreBatonets , un.nbreJoueurs
+ deux.nbreJoueurs, noms);
}

public static Jeu operator- (Jeu b,int a)
{
return new Jeu(b.nbreBatonets - a, b.nbreJoueurs, b.noms);
}
public static implicit operator int(Jeu a){return a.nbreJoueurs;}
public static explicit operator Jeu(int a){return new Jeu(a,2,"Pop", "Crov");}
// ( Remettre initGame, Tour, Perdu et ~Jeu de lexemple prcdent )
}
class Program
{
static void Main()
{
int c;
Jeu jeu = new Jeu();
Jeu a = jeu + new Jeu(25, 3, "Riri", "Fifi", "Knight who say NI!");
a = a - 12;
c = a;
a += (Jeu)c;
while (a.Tour());
Console.WriteLine(a.Perdu());
Console.ReadKey();
}
}

Ainsi implment, laddition permet de crer un jeu ayant les joueurs en commun, le nombre
de btonnets initial additionn (du fait quils soient en readonly je suis oblig de recrer une
instance). On peut songer par exemple dans une ventuelle volution du jeu en rseau fusionner les
salles de jeux par un simple oprateur +, avec ce mme oprateur en cast implicite vers un int
connaitre le nombre de joueurs dans les instances dun serveur. On pourrait aussi partir de loption
nbreBatonets gnrer en un cast une instance approprie par dfaut.

3.6.4 Delegate
Le delegate est comme un pointeur de fonction, c'est--dire une variable qui indique une
fonction pouvant sutiliser comme telle. Ce principe permet de passer une mthode en argument et
aussi de pouvoir modifier lexcution suivant ltat dune variable delegate. On commence par
gnrer un type de dlgu, puis ou peut dclarer des dlgus avec un degr daccs inferieur ou
gal celui du type. Le type de dlgu correspond une signature, un type dlgu indique les
types des arguments et le type de retour de la mthode que le dlgu associ va contenir. Lintrt
de crer des types de dlgus est avant tout de scuriser le code et de savoir comment utiliser le
dlgu. De plus si on entre dans un dlgu une mthode qui a plusieurs surcharges, linterprteur
dduira la quelle prendre pour que les signatures entre la surcharge et le type de dlgu
correspondent.

Lexemple ici montre plus un exemple dutilisation que lutilit relle des dlgus, mais
dautres exemples pourront vous clairer sur lutilit ds la partie prochaine.

C#




1er avril 2008
29 C# : Lessentiel en concentr

using System;

class testDelegate
{
public delegate int typeDeDelegue(ref int a);//Dclaration : type de dlgu
//les mthodes associes devront rpondre sa signature : int nom(ref int var)
public static int incrementer(ref int Nombre)
{
return ++Nombre;
}
}
class Program
{
static void Main()
{
int Valeur = 0;
//ci dessous on dclare une instance du dlgu
testDelegate.typeDeDelegue a = testDelegate.incrementer;
// le dlgu sans parenthse correspond la variable
// la mthode sans parenthse correspond l'adresse
while (a(ref Valeur) < 100) ;
// avec parenthses la mthode est excute.
Console.WriteLine(Valeur);
Console.ReadKey();
}
}

Les types de dlgus sont accessibles comme des lments statiques. Dans cet exemple
simple nous avons utilis a comme un pointeur ver la mthode incrmenter. Nous pouvons aussi
utiliser des dlgus en paramtres, nous verrons cela dans la partie qui suit. Notez le point virgule
aprs le while : seule la condition sera excute jusqu tre fausse.
3.6.5 Les vnements
Les vnements font parti dun type de programmation part entire, on parle de
programmation vnementielle qui soppose partiellement la programmation procdurale. La
programmation vnementielle consiste ragir en fonction des vnements. Les applications
interfaces graphiques sont souvent associes aux concepts de programmation vnementielle. Par
exemple, un utilisateur qui clique sur un des boutons de linterface lance une procdure. Le fait que
lutilisateur puisse tout moment agir sur nimporte quel bouton entend que ce nest pas une
procdure variable qui se droule de manire uniforme. Cest bien agir en fonction des
interactions. Dans nos exemples nous allons utiliser sans quitter notre console les vnements pour
voir leur fonctionnement.

C#

this.button1 = new System.Windows.Forms.Button()
this.button1.Click += new System.EventHandler(this.button1_Click);

Les vnements sont des dlgus voire des listes de dlgus qui sappellent peut prt
comme de simples mthodes. Dans lextrait gnr de WinForm ci-dessus nous voyons que le bouton
a par dfaut un vnement existant. Le plus souvent ce type de dlgu sera celui du framework :
EventHandler (Nous verrons quelle signature correspond ce type de dlgu).

Lvnement ntant pas une notion trs simple intgrer jai propos deux exemples. Les
vnements se dclarent avec le mot clef event et un type de dlgu. Un vnement ne peut
tre excut que depuis la classe il est dclar mais peut tre modifi depuis une autre sil est public.

C#




1er avril 2008
30 C# : Lessentiel en concentr

using System;

class exemple1
{
// EventHandler est un dlgu de mme signature que celui-ci-dessous.
// public delegate void elem(object sender,EventArgs e) ;
// public event elem evenement;
public event EventHandler evenement;

public void add_evenement(int i)
{
// evenement(this, EventArgs.Empty); (lve une exception si aucune mthode
assicies)
switch (i)
{
case 1:
evenement+=new EventHandler(exemple_evenement1);
break;
case 2:
evenement += new EventHandler(exemple_evenement2);
break;
case 3:
evenement += new EventHandler(exemple_evenement1);
evenement += new EventHandler(exemple_evenement2);
break;
default:
evenement -= new EventHandler(exemple_evenement1);
break;
}
}
public void execute()
{evenement(this, EventArgs.Empty);}
public static void exemple_evenement1(object sender, EventArgs e)
{Console.WriteLine("execution de la mthode 1");}
public static void exemple_evenement2(object sender, EventArgs e)
{Console.WriteLine("execution de la mthode 2");}
}

class Program
{
static void Main()
{
exemple1 a = new exemple1();
for (int i=1; i < 6; i++)
{
Console.WriteLine(i.ToString() + "________\n");
a.add_evenement(i);
a.execute();
}
System.Console.ReadKey();
}
}

Dans notre premier exemple lvnement est utilis de manire trs procdurale. Dans le
deuxime exemple bien que ce ne soit pas vident en console nous allons montrer quelque chose de
plus vnementiel , nous allons loguer ltat dune variable.

C#

using System;

class exemple2
{
public delegate void evenementHandler(exemple2 sender, EventArgs e);
public event evenementHandler lit;




1er avril 2008
31 C# : Lessentiel en concentr
public event evenementHandler ecrit;
protected string _logable;
public string Logable
{
get
{
if(lit != null)lit(this,EventArgs.Empty);
return _logable;
}
set
{
_logable=value;
if (ecrit != null) ecrit(this, EventArgs.Empty);
}
}
public bool switchLog()
{
if (lit == null && ecrit == null)
{
lit = new evenementHandler(accesLecture);
ecrit = new evenementHandler(accesEcriture);
return true;
}
lit = null;
ecrit = null;
return false;
}
public static void accesLecture(exemple2 sender, EventArgs e)
{
Console.WriteLine("Accs en lecture:" + sender._logable);
}
public static void accesEcriture(exemple2 sender, EventArgs e)
{
Console.WriteLine("Accs en ecriture:" + sender._logable);
}
}

class Program
{
static void Main()
{
exemple2 b = new exemple2();
b.switchLog();
b.Logable = "test";
b.Logable = b.Logable;
Console.WriteLine(b.Logable);
b.switchLog();
b.Logable = "sans log c'est moins verbeux";
b.Logable = b.Logable;
Console.WriteLine(b.Logable);
System.Console.ReadKey();
}
}

Le terminal nest pas la plus adapt des interfaces pour parler dvnements mais jespre
que ces exemples vous suffiront pour vous approprier les notions dvnements qui seront utiliss
dans de vrais programmes .NET.
3.6.6 Mthodes anonymes et Expressions lambda
Les mthodes anonymes fait partie des nouveauts du C#2.0. Cet outil permet de crer une
mthode point par un dlgu sans avoir la mettre dans une classe : Lutilisation est simple :

C#

using System;




1er avril 2008
32 C# : Lessentiel en concentr
class testDelegate
{
public delegate void NoArg ();
public delegate void ArgDelegate(NoArg a);
public void executer10Fois(NoArg fonction)
{
for(int i=0;i<10;i++) fonction();
}
public void executer10Fois(ArgDelegate fonction,NoArg argument)
{
for (int i = 0; i < 10; i++) fonction(argument);
}
}
class Program
{
static void Main()
{
testDelegate var = new testDelegate();
testDelegate.NoArg afficheA = delegate() { Console.Write("a"); };
var.executer10Fois(afficheA);
Console.WriteLine("\n_________________________\n");
testDelegate.ArgDelegate a = var.executer10Fois;
// var.executer10Fois(a,afficheA) ; ou plus instructif :
var.executer10Fois
(
delegate(testDelegate.NoArg fonction){for(int i=0;i<10;i++) fonction();},
delegate() { Console.Write("a"); }
);
Console.ReadKey();
}
}

Voici un exemple assez simple et tordu la fois, il nous montre une partie du potentiel des
dlgus quels quils soient. Notez que les dlgus anonymes sont typs automatiquement pour
entrer dans la variable ou en argument. Vous pouvez facilement imaginer une attribution
conditionnelle dans la quelle le formatage dpendra de la mthode point par la variable dlgue.

Remarque : la partie qui suit sur lexpression lambda et les mthodes dextension est compose
essentiellement de nouveauts du C# 3.0, si vous dveloppez sur un logiciel existant, il vous faudra
spcifier de compiler avec la syntaxe C# 3.0 qui est rtro compatible pour pouvoir faire ce qui vas
suivre.

Les expressions lambda sont des dlgus anonymes limits une instruction, la syntaxe est
claire, rapide et lisible mais on ne peut mettre de boucles. Si le type de dlgu attendu a un type de
retour, la seule instruction de lexpression lambda sera retourne.
La syntaxe de lexpression lambda est simple : les paramtres du dlgu anonyme, le signe
=> puis linstruction.

C#

(int arg1, int arg2) => arg1+ arg2 //delegate(int arg1,int arg2){return arg1+arg2;}
arg => arg + 4 // delegate(int arg){return arg+4;}
// Le type du paramtre prcdent dpend du type
// dlgu attendu (donc pas forcment int)
() => Console.Write("a") // delegate(){Console.Write("a");}

Voici trois exemples hors contexte. Si on ne spcifie pas le type il est spcifi
automatiquement et sil y a un seul paramtre typ implicitement pas besoin des parenthses pour
lisoler. Refaisons la mme chose que tout lheure avec ces lambda expressions.





1er avril 2008
33 C# : Lessentiel en concentr
C#

using System;
class testDelegate
{
public delegate void NoArg ();
public delegate void ArgDelegate(NoArg a);
//ici on dclare une instance du dlgu
public void executer10Fois(NoArg fonction)
{
for(int i=0;i<10;i++) fonction();
}
public void executer10Fois(ArgDelegate fonction,NoArg argument)
{
for (int i = 0; i < 10; i++) fonction(argument);
}
}
class Program
{
static void Main()
{
testDelegate var = new testDelegate();
testDelegate.ArgDelegate a = var.executer10Fois;
var.executer10Fois
(
//(testDelegate.NoArg fonction) => a(fonction),
fonction => a(fonction) ,
() => Console.Write("a")
);
Console.ReadKey();
}
}

Nous avons vu lessentiel sur les mthodes et les dlgus, nous allons dsormais voir
comment on peut lier nos mthodes des objets du framework.

3.6.7 Mthode dextension.
Les mthodes dextensions sont des mthodes statiques qui permettent de sutiliser comme
si elles taient propre une classe autre que celle dans la quelle elle est dfinie. Je mexplique, si
vous voulez faire une mthode de traitement de string, vous nallez pas pouvoir modifier la classe
string du framework pour ajouter une mthode de traitement, donc vous allez devoir crer une
classe avec une mthode statique puis faire appel cette classe pour le traitement. La mthode
dextension permet dappliquer la mthode statique comme si elle tait dans la classe. Par exemple
ci dessous on cre une mthode qui permet de navoir crire que var.Write() avec var variable de
type string au lieu de faire Console.WriteLine(var).

C#

using System;
static class StringToolBox
{
static int titleIndex = 0;
public static void Write(this string s)
{
Console.WriteLine(s);
}
public static string titleFormat(this string s,int i)
{
return
"\n" + "_" + (++titleIndex).ToString() + "_" +
s.ToUpper() + "_" + i.ToString() + "_" + "\n" ;
}




1er avril 2008
34 C# : Lessentiel en concentr
}
class Program
{
static void Main()
{
for(int i=0;i<10;i++)
("bonjour "+"Monsieur").titleFormat(i).Write();
Console.ReadKey();
}
}

Le mot clef qui sert spcifier que la mthode est une mthode dextension est le mot clef
this, on mettra toujours ce this avec le premier argument (qui est lobjet qui prcde le point lors de
lappel).

3.6.8 Itrateurs
Certaines mthodes sont appeles des itrateurs, elles utilisent le mot clef yield. Ces
mthodes retournent des objets IEnumerable ou IEnumerator (Nous privilgierons IEnumerable qui
peut tre utilise dans un foreach). Nous allons voir comment faire avec et sans le foreach pour que
vous puissiez comprendre comment sont les objets que nous utilisions. IEnumerable et IEnumerator
ne contiennent pas le rsultat mais le moyen dy accder, pour preuve, lexemple modifiera le
rsultat aprs la dclaration de lnumrable et le parcourra deux fois avec deux rsultats diffrents.

C#

using System;
using System.Collections;
static class StringTB
{
public static int I = 0;
public static void Write(this string s)
{
Console.WriteLine(s);
}
public static IEnumerable titleFormat(this string s, int limit)
{
for (int i =1;i<=limit;i++)
yield return
"\n"+"_"+i.ToString()+"_"+s.ToUpper()
+"_"+(++I).ToString()+"_"+"\n";
yield break;
}
}

class Program
{
static void Main()
{
IEnumerable enumerable = "bonjour Monsieur".titleFormat(100);
// on a cr l'numrable avec titleFormat

IEnumerator enumerateur = enumerable.GetEnumerator();
// on extrait l'numrateur

StringTB.I = 5;
// on procde une modification qui changera le rsultat
// conclusion rien n'as encore t calcul.

for (int i = 0; i < 100; i++)
{
// si on ne commenait pas par un MoveNext le premier rsultat serait "null"
enumerateur.MoveNext();




1er avril 2008
35 C# : Lessentiel en concentr
string s = enumerateur.Current as string ?? "erreur";
// caste en string (si impossibles contiendra "erreur")

StringTB.I = StringTB.I % 10 == 0 ? StringTB.I * 2:StringTB.I;
// multiplie par 2 toutes les 10 itrations I
// conclusion : les strings sont calculs au fur et mesure

s.Write();
}
StringTB.I = 0;
Console.ReadKey();
// parcour avec foreach:
foreach (string s in enumerable)
s.Write();
Console.ReadKey();
}
}

Yield est un mot clef qui est central dans le linq bien que relativement cach, cette technologie
vous permet de jouer avec des numrables, de les imbriqus avec une facilit tonnante, et bien-
sur laccs en lecture, a excute le ncessaire pour accder la donne.
Yield nest utilisable quavec un des deux mots clefs qui suit : Return et Break. Yield return
ajoute une entre dans lnumrateur et yield break arrte lexcution du block. Yield break employ
dans notre exemple, il ne sert rien.

3.7 Lhritage, le polymorphisme et les interfaces
3.7.1 Introduction
Lhritage est un moyen doffrir aux classes toutes les mthodes et tous les attributs public et
protected dune classe existante. Contrairement au C++, le C# ne permet pas dhriter de plusieurs
classes bien que les interfaces permettent de faire un quivalent. Lhritage conduit des similitudes
entre les objets et donc de la simplicit pour apprendre. Nous ne lavions pas vu mais tous les objets
hritent de lobjet object . Object est la classe la base de tout, cest object qui implmente la
mthode ToString que lon a beaucoup utilis. Cette mthode tant de la classe mre universelle ,
elle est implmente par dfaut par toutes les classes.
Le polymorphisme dans le framework est un outil pratique qui permet par exemple de ranger
dans une liste type des objets de classes diffrentes pour peu quils se comportent pareil. Tous les
objets peuvent tres appels comme des objets dun de leurs types parents. De ce fait toutes
variables quelque soient leur type peuvent tre utilis comme des variable de type object. Toute
variable peut tre passe en argument dune mthode qui attend un objet de type object .

Les interfaces sont des espces de classes qui ne servent qu tre hrites (dans le cas
dune interface, on dit quelle est implmente ). Quand on implmente une interface on garanti
un comportement, si on implmente par exemple linterface IEnumerable, notre objet pourra
bnficier de linq et tre numr dans un foreach. Dans lexemple prcdant on utilisait
IEnumerable et IEnumerator comme les types des variables mais cest juste grce au fait que le
polymorphisme marche avec les interfaces en plus des classes mres. De ce fait peut importe le type
de retour qui entrera la donne dans ma variable ds lors que ce type implmente linterface
IEnumerable car ce retour aura forcment le comportement attendu.

Lorient objet initie des nouveaux mots-clefs de restriction de droits, commenons par
rexpliquer les mots que nous connaissons dj dans ce contexte dhritage :
public : Les lments public dune classe sont lgus aux classes enfantes.
protected : Les lments protected dune classe sont lgus aux classes enfantes.




1er avril 2008
36 C# : Lessentiel en concentr
private : Les lments private dune classe ne sont pas hrit aux classes enfantes.
static : On ne peut pas faire hriter une classe spcifie en static. Les lments
statiques dune classe non statique qui sont en public ou protected peuvent tres
accds par les classes enfante mais ne sont pas proprement parl hrites. Le
mot clef base permet daccder aux lments de la classe mre sans se soucier
de son nom (sutilise comme this ). Comme les classes statiques ne peuvent
hriter il est vu comme un non sens que de spcifier des lments en protected, de
ce fait on utilisera public ou private.

Voici une liste de quelques nouveaux mots clefs initis par la notion dhritage:
sealed : Aucune classe de peut hriter dune classe dune mthode ou dune
proprit sealed (si on veut quun lment soit public sans que les classes filles en
hrite par exemple).
abstract : Les classes abstraites ne sont pas utilisables directement, elles ne servent
que de classes mre pour faciliter et regrouper la construction dobjets de mme
forme. Les lments abstraits dune classe eux doivent tre dfini, ils sont comme
des contraintes de mthodes et variable interne dfinir. (Une classe abstract ne
peut tre instanci)
virtual : virtual est fonctionnellement comme abstract une diffrence prt : dans la
classe mre il y a une implmentation par dfaut que lon peut ne pas redfinir.

Le framework utilise beaucoup lhritage et ce modle de polymorphisme, nous allons
revenir sur les exceptions qui hritent toutes de la classe exception qui elle mme hrite de Object.

3.7.2 Exemples dhritage : les exceptions et throw
Cet exemple est coupl avec celui de la partie 2.5. Dans ce deuxime exemple je cre un
nouveau type dexception dont je ne redfini que le Constructeur. Ce type dexception a les mmes
attributs et les mmes proprits que lexception par default au dtail prt quil na quun
constructeur. Pour dfinir les variables comme dans une exception standard simplement, jajoute
mon constructeur le constructeur de la classe Exception.

C#

using System;
class MonException : Exception
{
public MonException() : base("Le problme est de type custom")
{
Console.WriteLine("Erreur spciale avec mon excution");
}
}
class Program
{
public static void Main()
{
Random r = new Random(DateTime.Now.Millisecond);
while (true)
{
if (1 >= r.Next(0,100000000))
{
MonException e = new MonException();
try
{
throw e;
}
catch (MonException except)




1er avril 2008
37 C# : Lessentiel en concentr
{
Console.WriteLine(except.ToString());
}
finally
{
e = null;
}
}
}
}
}

La nouvelle classe est instancie et leve comme nimporte quelle exception. Le mot clef
throw permet de lever une instance dexception, il sera plus commun de voir throw new
MonException() ; mais ctait pour justifier lusage dun block finally pour la ds-allocation de
mmoire.

Dans lexemple de la partie 2.5 on peroit plus nettement le polymorphisme mais nous
aurons loccasion dy revenir.
3.7.3 Redfinition de mthodes et dattributs
Le constructeur est une redfinition particulire vu que le nom nest pas le mme mais pour
les classes ou les lments abstract on se verra oblig de redfinir des lments qui existent dj ce
qui normalement est impossible. Nous allons utiliser deux mots clefs trs similaires dans ce
contexte : override et new.

C#

using System;
abstract class mere
{
public abstract int longueur { get;}
public abstract int largeur { get; set; }
public virtual int aire() { return longueur*largeur;}
public virtual void printAire() { Console.WriteLine(longueur*largeur); }
}
class fille : mere
{
private int la;
private int lo;

public override int largeur
{
get { return la; }
set { la = value; }
}
public override int longueur
{
get { return lo; }
}
public fille()
{
la = 6;
lo = 5;
}
public new int aire() {return (largeur+longueur)*2;}
public override void printAire()
{
Console.WriteLine((largeur + longueur) * 2);
// base.printAire();
}
public override string ToString()
{




1er avril 2008
38 C# : Lessentiel en concentr
return "on peut dfinir comment ragi la mthode .ToString comme ceci" ;
}
}
class Program
{
public static void Main()
{
mere m = new fille();
fille f = new fille();
Console.WriteLine("affichage cast en mre puis en fille (override)");
m.printAire();
f.printAire();
Console.WriteLine("retour d'aire cast en mre et en fille (new)");
Console.WriteLine(m.aire() + "\n" + f.aire());
Console.ReadKey();
}
}
Retour Console:

affichage cast en mre puis en fille (override)
22
22
retour d'aire cast en mre et en fille (new)
30
22

Dans cet exemple on a une classe abstraite mre et une classe fille. Quand vous tentez
dimplmenter une proprit ou une mthode, vous verrez que votre IDE (Visual Studio ou
MonoDevelop) vous propose directement la structure de base. La syntaxe des proprits de la classe
mre est encore une nouveaut du C#3.0, on dfinie ce qui sera implmenter. La ligne commente
montre comment jaurais pu par exemple appeler la mthode par dfaut implmente par la classe
mre.

Lexemple risque dtre un bon complment dexplication sur la diffrence entre la
redfinition avec override et la redfinition avec new.
New : permet de crer une mthode propre la classe fille qui sera appele normalement
sur une instance de cette classe fille. Si linstance de la classe fille est range dans une
variable de type de la classe mre si la mthode homonyme est appele ce sera la mthode
par dfaut de la classe mre qui sera appele et non celle de la classe fille.
Override : permet quand lui de remplacer rellement la mthode de la classe mre pour
linstance de la classe fille quelque soit le contexte.
3.7.4 Les interfaces
Les interfaces sutilisent comme des classes abstraites, on peut les implmentes comme on
hriterait dune classe. On dfini dans linterface des mthodes et proprits avoir pour
implmenter linterface pour pouvoir bnficier du polymorphisme li. Si on caste lobjet avec
linterface, seules les mthodes qui relvent de linterface seront accessibles.

Cest donc une forme dhritage multiple. Si lon repense aux mthodes dextensions, je
vous laisse comprendre lintrt du polymorphisme, pouvoir rduire le code et ne pas avoir le
refaire pour chaque classe. Certaines interface comme IEnumerable sont au cur du framework,
cette interface doit tre implmente que ce soit pour utiliser le mot clef yield, pour pouvoir utiliser
foreach, pour pouvoir utiliser Linq2object

Les mthodes des interfaces peuvent tres implmentes de deux faons : implicitement ou
explicitement. Les interfaces on toujours tous leurs attributs publics, cest pourquoi le degr daccs




1er avril 2008
39 C# : Lessentiel en concentr
nest pas demand dans la dclaration de linterface. On ne peut pas faire de mthode virtual, les
interfaces tablissent une structure respecter

C#

using System;
interface Imere
{
int longueur { get;}
int largeur { get; set; }
void aire();
void printAire();
}

class fille : Imere
{ private int la;
private int lo;
public fille()
{la = 6;lo = 5;}

#region Imere Membres
// implmente explicitement
int Imere.longueur
{ get { return lo; }}
// implmente implicitement
public int largeur
{ get { return la; }
set { la = value; }}

// implmente explicitement
void Imere.aire()
{Console.WriteLine((largeur+ ((Imere)this).longueur)*2);}

//Implment implicitement
public void printAire()
{Console.WriteLine((largeur + ((Imere)this).longueur) * 2);}

#endregion
}

class Program
{
public static void Main()
{

Imere m2 = new fille();
fille f2 = new fille();
Console.WriteLine("affichage cast en interface puis en fille (implicit)");
m2.printAire();
f2.printAire();

Imere m = new fille();
fille f = new fille();
Console.WriteLine("retour d'aire cast en Imre et en fille (explicit)");
m.aire();

/********************************************************************
* la ligne qui suit ce commentaire ne passe pas la compilation.
* Erreur 1:
* 'fille' ne contient pas une dfinition pour 'aire' et aucune mthode d'extension
* 'aire' acceptant un premier argument de type 'fille' n'a t trouve
* (une directive using ou une rfrence d'assembly est-elle manquante ?)
********************************************************************/
// f.aire();
Console.WriteLine("erreur\n\nutilisons une liste maintenant");
Imere[] list = new Imere[] { f, m, m2, f2 };
foreach (var e in list)




1er avril 2008
40 C# : Lessentiel en concentr
e.aire();
Console.ReadKey();
}
}

3.7.5 Les attributs
Les attributs sont des classes hritant de attribut, leurs usage sert modifier le comportement
dlments (classes, enums, structs, mthodes). Les attributs ont une syntaxe particulire utilisant les
crochets ( [ ] ).
Un exemple pratique ou les attributs sont utiliss cest la srialisation. Lusage dun simple
attribut permettra de ranger assez facilement dans un fichier XML toutes les donnes dun objet. Et
avec un simple attribut on peut demander ce quun des champs ne soit pas srialis. Je ne vais pas
vous insister sur la syntaxe pour srialiser (o il faut crer un flux vers un fichier texte) mais montrer
comment rendre srialisable une classe. Si vous voulez excuter cet exemple vous aurez besoin de la
rfrence System.Runtime.Serialization.Formatters.Soap .

C#

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;

[Serializable()]
public class ExempleSerialisation
{
public int serialise;

[NonSerialized()]
public string nonserialise;

public ExempleSerialisation()
{

serialise = 1337;
nonserialise = "mon nom est Jirfongrifengrafterg";
}
public void affichage()
{
Console.WriteLine("lment srializ = "+ serialise.ToString());
Console.WriteLine("lment non srializ = "+ nonserialise);
}
}

public class Program
{
public static void Main()
{
ExempleSerialisation variable = new ExempleSerialisation();
variable.affichage();

// La partie qui suit permet de srialiser et dsrialiser,
// je ne m'atarderait pas dessus, le sujet tant les attributs.
Stream stream = File.Open("variable.xml", FileMode.Create);
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(stream, variable);
stream.Close();
Console.WriteLine("srialisation finie\ndsrialisation:");
variable = null;
stream = File.Open("variable.xml", FileMode.Open);
formatter = new SoapFormatter();
variable = (ExempleSerialisation)formatter.Deserialize(stream);
stream.Close();




1er avril 2008
41 C# : Lessentiel en concentr
Console.WriteLine("dsrialisation finie.");
variable.affichage();
Console.ReadKey();
}
}
Retour Console:

lment srializ = 1337
lment non srializ = mon nom est Jirfongrifengrafterg
srialisation finie
dsrialisation:
dsrialisation finie.
lment srializ = 1337
lment non srializ =


Lattribut *Serializable()+ a automatiquement implment le ncessaire pour que la classe
puisse tre srialise. Nous ne voulions pas retenir un des champs, nous avons mis [NonSerialized()].
Lattribut ce place au dbut de llment et sapplique sur sa globalit.

C#

using System;
static class StringToolBox
{
static int titleIndex = 0;
public static void Write(this string s)
{
Console.WriteLine(s);
}
[Obsolete()]
public static string titleFormat(this string s, int i)
{
return
"\n" + "_" + (++titleIndex).ToString() + "_" +
s.ToUpper() + "_" + i.ToString() + "_" + "\n";
}
}

Voil un autre attribut simple pour mentionner quune mthode est dvalu. Lenvironnement
de dveloppement prcisera les mthodes que lon compte retirer aux dveloppeurs pour les inciter
en utiliser dautres sils prvoient de mettre jour la librairie contenant la classe. Lattribut
Obsolete peut se mettre sur nimporte quel lment. Tous les attributs sont des classes hritant de
System.Attribute.
4 Conclusion
Nous avons trait de manire trs synthtique un sujet quasiment inpuisable, le framework
.NET vous permettra dutiliser les connaissances de ce tutorial pour crer des sites web, crer des
applications fentres, faire des applications graphiques, des librairies Bref, vous pourrez faire
quasiment presque tout ce qui est programmable avec le framework et le C#. Nous avons abord de
prs ou de loin tous les mots clefs du C# lexception de quelques uns (volatile, lock, external et
where).

Pour rappel nous avons vu :
Lhistoire et fonctionnement du C#
Les types valeurs et string
Les oprateurs




1er avril 2008
42 C# : Lessentiel en concentr
Les conditions
Les boucles
Les Arrays
Comment grer les erreurs
Comment utiliser les pointeurs hrits du C++
Les espaces de nom
Les modificateurs daccs, les attributs et les proprits
Les mthodes dont Main, les constructeurs et les destructeurs
La surcharge des mthodes
Les dlgus, vnements, et expressions lambda
Les itrateurs
Lhritage
Le polymorphisme
Les interfaces
Les attributs

Pour tirer pleinement partie de ce premier tutoriel, vous devriez songer aborder dautres
cours de DotNet-France, vous avez dsormais le niveau requis. Voici les cours ver les quels vous
pourriez vous orienter.
Vous vous intressez aux applications fentres ? vous pouvez vous diriger vers le
tutoriel traitant des WinForm.
Vous voulez faire des sites web ? le tutoriel ASP.NET WebForm.
Vous voulez faire par exemple un jeu vido, intressez vous peut tre au tutoriel XNA.
Vous vous intressez laccs aux bases de donnes et fichiers XML, le tutoriel ADO.NET
est aussi l pour vous.
Vous vous intressez linteroprabilit et aux applications Unix ? peut tre devriez
vous vous diriger ver le tutoriel Mono.
Vous voulez amliorer vos connaissances globales sur les rouages du framework ? Le
tutoriel traitant du framework devrait vous satisfaire.

Cette liste vous donne dj un avant got de ce que vous pourrez faire avec le C#. Jespre
que ce chapitre ne vous a pas perdu, et mme ouvert une envie au dveloppement .NET, nhsitez
pas a garder ce tutoriel sous le coude comme manuel de rfrence, car je ne pense pas que lon
puisse tout intgrer dune seule traite.

Vous aimerez peut-être aussi