Cours C#
Cours C#
Cours C#
Base du langage C#
C# est un langage introduit par Microsoft en 2000. C’est un langage objet avec un
typage statique fort, une syntaxe héritée du C/C++ et une philosophie très proche de
Java. C# est un langage phare du framework .net qui se popularise pour la
conception de sites Web (ASP), d’ERP (Sharepoint), de scripting et d’applications
lourdes.
A l’origine considéré comme une pâle copie de Java, le C# a ensuite bénéficié d’une
politique de développement très dynamique par rapport à Java, resté en désérence
plusieurs années par Sun avant son rachat par Oracle. Aujourd’hui, C# est un
langage de programmation moderne avec une bibliothèque standard très riche et des
outils de développement avancés.
Les commentaires
Les commentaires sont introduits comme en C/C++ et Java :
sur une seule ligne: tout ce qui suit les caractères // est ignoré jusqu’à la fin de
la ligne;
sur plusieurs lignes: tout ce qui se trouve entre les balises /* et */ est ignoré.
// Je suis un commentaire sur une seule ligne.
Déclaration
Avant de pouvoir utiliser une variable il faut la déclarer avec la syntaxe suivante :
Syntaxe
TypeDeDonnee Identificateur;
TypeDeDonnee Identificateur = ValeurInitiale;
Exemples :
int unEntier;
float unNombreFloatant = 3.0; // déclaration de la variable unNombreFloatant de type
float et initialisation
Bitmap uneImage; // déclaration de la variable uneImage de type Bitmap
Avertissement
Une variable peut être déclarée sans être initialisée : sa valeur est alors indéfinie.
Essayer de lire une variable alors que sa valeur est indéfinie est une erreur de
compilation en C#.
Les identificateurs ne peuvent pas être des mots clés du langage ( int , if , else …).
Types de données
Le langage C# est
fortement typé : il est interdit de mettre une valeur dans une variable si les types
de la variable et de la valeur ne sont pas compatibles;
manuellement typé : les informations de typage sont données par le développeur;
statiquement typé : le typage est vérifié par le compilateur et toute erreur
empêche la compilation du programme;
dynamiquement typé : le CLR vérifie également l’intégrité des types à l’exécution.
Chaque variable est associée à un type donné. Ces types sont divisés en 2
catégories:
1. Les types valeurs composés des types primitifs (types de base du langage) et
des structures (non traitée dans ce cours). Pour cette catégorie, l’emplacement
mémoire correspondant à la variable contient directement la valeur concernée.
Type de Taille
Genre Valeurs possibles
données (octets)
nombre
byte
entier
1 00 à 255255
nombre
short
entier
2 −215−215 à 215−1215−1
nombre
int
entier
4 −231−231 à 231−1231−1
nombre
long
entier
8 −263−263 à 263−1263−1
decimal
nombre
16
−7.9×1028−7.9×1028 à 7.9×10287
réel .9×1028
valeur
bool 1 true ou false
booléenne
Constantes littérales
Les constantes littérales, c’est-à-dire, les valeurs rentrées directement dans le code
sont typées :
1 // est un entier (le type exacte byte, short, int ou long sera déteminé par le
contexte)
1.0 // est un double
1.0f // est un float
'c' // est un caratère
true // est un booléen
Transtypage
Le transtypage ou cast désigne l’action de transformer une valeur d’un type de
données vers un autre type. Pour caster une valeur dans un nouveau type, il faut
indiquer le nom du nouveau type entre parenthèses devant la valeur:
double d = 2.1;
int i = (int)d; // d est casté en int, i contient la valeur 2: la partie décimale est
supprimée
Ce mécanisme est très complexe dans les langages modernes, chaque couche
d’abstraction générant de nouvelles règles (polymorsphime paramétriques,
polymorphismes d’héritage, généricité, template, duck typing). Cela mène à des
résultats surprenant lorsque l’on ne maitrise pas bien ces mécanismes. Par exemple,
ruby et javascript sont connus pour leurs conversions implicites hasardeuses alors
que les interractions entre conversions implicites et templates de la librairie standard
du C++ génère des messages d’erreurs interminables et difficilement
compréhensibles .
Expression
Une expression est une combinaison de variables, d’opérateurs, de constantes et
d’appels de fonction. Comme les variables, les expressions ont une valeur et un type.
Par contre les expressions ne sont pas identifiées par un nom. Le calcul de la valeur
d’une expression est appellé évaluation.
int x = 2;
int y = x + 2; // x + 2 est une expression de type int et de valeur 4
bool b = y >= 5; // y >= 5 est une expression de type bool et de valeur false
Les règles de priorité classiques sont utilisées lors de l’évaluation d’une expression
(par exemple la multiplication est prioritaire sur l’addition).
Les parenthèses permettent de changer l’ordre d’évaluation des différentes parties
d’une expression et de clarifier la lecture.
Opérateurs simples
La liste des opérateurs du C# est assez longue, les plus communs sont:
Opérateur d’affectation =
y = x; // y = 1
y = y + 1; // y = 2, x n'est pas modifié et vaut toujours 1
Dans le cas d’un type référence, la valeur stockée dans la variable étant la référence,
l’opérateur d’affectation copie cette référence et non l’objet référencé.
Il existe une variante de l’opérateur d’affectation pour chaque opérateur binaire. Par
exemple l’opérateur dérivé += permet d’ajouter une valeur à une variable:
int x = 3;
x += 2; // équivalent à x = x + 2;
if
Syntaxe
if ( condition )
{
// instructions à réaliser si CONDITION vaut true
} else {
// instructions à réaliser si CONDITION vaut false
}
for
Syntaxe
for ( initialisation; condition; instructionDIteration )
{
// bloc d'instructions à réaliser tant que condition vaut true
}
while
Syntaxe
while ( condition )
{
// bloc d'instructions à réaliser tant que condition vaut true
}
Les fonctions
Une fonction est une portion de code qui effectue une tâche ou un calcul. Une
fonction est désignée par un identificateur qui permet de l’appeler à partir d’autres
endroits du programme, c’est-à-dire de demander à exécuter la portion de code qui
correspond à la fonction. La fonction peut retourner une valeur, c’est-à-dire renvoyer
un résultat. Une fonction peut prendre des arguments ou paramètres qui désignent
les données d’entrée sur lesquelles travaille la fonction.
Déclaration
La déclaration d’une fonction se fait en 2 parties :
On commence par donner son prototype qui contient toutes les informations
d’identification de la fonction: son nom, ses paramètres, son type de retour…
Puis on donne son corps entre accolades qui contient les instructions de la
fonction.
Syntaxe
TypeDeRetour IdentificateurFonction(TypeParametre1 identificateurParametre1, TypeParametre2
identificateurParametre2, ...) // prototype
{ // début du corps
// intructions de la fonction
return valeurDeRetour;
} // fin du corps
Une fonction qui ne retourne pas de résultat utilise le type de retour special void (qui
signifie rien). Les fonctions qui ne retournent rien sont appelées procédures.
Syntaxe
void IdentificateurFonction(TypeParametre1 identificateurParametre1, TypeParametre2
identificateurParametre2, ...)
{
// intructions de la fonction
return; // optionnel, remarquez l'absence de valeur après l'instruction return
}
Attention
Les fonctions dont le type de retour est différent de void doivent se terminer par
l’exécution d’une instruction return suivie d’une valeur dont le type est compatible
avec le type de retour de la fonction. Le compilateur vérifie que, quelque soient les
paramètres d’entrée de la fonction, l’exécution de la fonction se termine toujours par
une instruction return . Ainsi le code suivant est faux et provoque le message
d’erreur : Tous les chemins de code ne retournent pas nécessairement une valeur :
int F3(int x)
{
if(x<2)
{
return 1;
}
}
Note
Par convention, les identificateurs de fonction en C# suivent la norme Camel Case
mais, contrairement aux identificateurs de variable, on fera commencer leur premier
mot par une majuscule.
Appel de fonction
Une fonction est appelée en indicant son identificateur suivi, entre paranthèses, des
valeurs des paramètres:
Syntaxe
IdentificateurFonction(valeurParamètre1, valeurParamètre2,...);
Un appel de fonction dont le type de retour est différent de void est une expression
qui a pour type le type de retour de la fonction et pour valeur la valeur retournée par
la fonction.
int Fonction2(int a)
{
a += 1;
return a;
}
void Fonction1()
{
int b = 7;
b = Fonction2(b); // Fonction2(b) est une expression de type int et de valeur 8
}
Important
Lors de l’appel d’une fonction, le passage des paramètres est toujours réalisé par
copie : la fonction reçoit une copie de la valeur passée en paramètre. Si la variable
est de type valeur, il s’agit d’une copie de cette valeur. Si la variable est de type
référence, il s’agit d’une copie de la référence.
void Increment(int a)
{
a += 1;
}
...
int x = 0;
Increment(x);
int y = x; // y vaut 0 !
void Fonction1()
{
int b = 7;
for(int i=0; i < 10; i++)
{
b = Fonction2(b);
} // i cesse d'exister ici
Déclaration et création
Etant donné un type T, la notation T[] désigne le nouveau type tableau d’éléments
de type T. Par exemple int[] désigne le type tableau d’entiers qui est différent du
type entier. On peut déclarer des variables avec ce type de données.
Pour créer un tableau, on utilise l’opérateur new . Les tableaux sont de type
référence.
Tableaux unidimentionnels:
Syntaxe
TypeDesElements [ ] monTableau1; // déclaration d'un tableau
TypeDesElements [ ] monTableau2 = new TypeDesElements [tailleDuTableau]; // déclaration et
création d'un tableau
int [ ] monTableau3 = {1, 5, 6, 7}; // déclaration d'un tableau et initialisation explicite
Tableaux multidimensionnels :
Syntaxe
TypeDesElements [,] monTableau1; // déclaration d'un tableau bidimentionnel
TypeDesElements [,,] monTableau2; // déclaration d'un tableau tridimentionnel
TypeDesElements [,] monTableau3 = new TypeDesElements [nombreDeLignes, nombreDeColonnes] ;
// déclaration et initialisation d'un tableau
int [,] monTableau4 = { {1, 5, 6},
{2, 9, 7} }; // déclaration d'un tableau 2d et initialisation
explicite
Les variables de type tableau sont commes les autres : elles doivent être initialisées
avant d’être utilisées. Lors de la création d’un tableau, chaque cellule du nouveau
tableau est initialisée par défaut. Ainsi, si vous créez un tableau d’entiers, chaque
case sera mise à zéro.
Accès aux éléments d’un tableau
Les cases d’un tableau sont numérotées de 0 à la taille du tableau moins un. Le
numéro d’une case est appelé son indice et permet d’accéder à cette case.
Syntaxe
int [] monTableau1 = {1, 2, 3};
monTableau1[0] = 4; //modification de la valeur de la case d'indice 0: monTableau1 = {4, 2,
3}
int a = monTableau1[2]; // lecture de la valeur de la dernière case du tableau: a = 3
L’accès à un indice invalide d’un tableau (en dehors d’un tableau) déclenche une
erreur à l’exécution.
foreach (bool valeur in monTableau) // se lit: "pour toute valeur de type bool dans
monTableau"
{
... valeur ...
}
Chaines de caractères
Les chaines de caractères sont désignées par le type String (ou string avec une
minuscule) qui est de type référence. Les constantes de type chaine de caractères
s’écrivent entre double quotes " .
string s1 = "Bonjour";
String s2 = "Bonjour";
String s3 = ""; // chaine de caractères vide