Introduction au langage C#
La syntaxe
1. Les identifiants
Les identifiants sont les noms donnés aux classes et à leurs membres. Un identifiant doit être composé d’un seul mot commençant par une lettre ou un caractère underscore (_). Les identifiants peuvent être composés de lettres majuscules ou minuscules mais le langage C# étant sensible à la casse, les majuscules et minuscules doivent être respectées pour faire référence au bon identifiant : monIdentifiant est différent de MonIdentifiant.
2. Les mots-clés
Les mots-clés sont des noms réservés par le langage C#. Ils sont interprétés par le compilateur et ne peuvent donc pas être utilisés en tant qu’identifiants. Ces mots-clés sont distingués dans l’éditeur de texte de Visual Studio en étant colorés en bleu (avec les paramètres d’apparence par défaut).
Si vous avez besoin d’utiliser un mot-clé en tant qu’identifiant pour un membre, il faut préfixer le nom de l’identifiant par le caractère @. La syntaxe suivante entraînera une erreur et le compilateur refusera de s’exécuter :
private bool lock;
En préfixant le membre lock par le caractère @, le compilateur considère que c’est un identifiant et non plus un mot-clé :
private bool @lock;
Le caractère @ peut également préfixer des identifiants qui n’ont aucun conflit avec les mots-clés, ainsi @monIdentifiant sera interprété de la même manière que monIdentifiant.
Voici une liste des mots-clés du langage C#. Ils seront expliqués, en partie, au cours de l’ouvrage :
abstract |
add |
as |
ascending |
async |
await |
base |
bool |
break |
by |
byte |
case |
catch |
char |
checked |
class |
const |
continue |
decimal |
default |
delegate |
descending |
do |
double |
dynamic |
else |
equals |
enum |
event |
explicit |
extern |
false |
finally |
fixed |
float |
for |
foreach |
from |
get |
global |
goto |
group |
if |
implicit |
in |
int |
interface |
internal |
into |
is |
join |
let |
lock |
long |
nameof |
namespace |
new |
null |
object |
on |
operator |
orderby |
out |
override |
params |
partial |
private |
protected |
public |
readonly |
ref |
remove |
return |
sbyte |
sealed |
select |
set |
short |
sizeof |
stackalloc |
static |
string |
struct |
switch |
this |
throw |
true |
try |
typeof |
uint |
ulong |
unchecked |
unsafe |
ushort |
using |
value |
var |
virtual |
volatile... |
Les espaces de noms
Les espaces de noms permettent d’organiser et de hiérarchiser les types. Un espace de noms peut être composé de plusieurs classes écrites dans différents fichiers et compilées dans différentes librairies. C’est le cas du Framework .NET qui regroupe une multitude de types organisés dans des espaces de noms.
1. Déclarer un espace de noms
Pour ajouter une classe à un espace de noms, il faut l’encadrer par le mot-clé namespace suivi du nom de l’espace de noms souhaité :
namespace MonEspace
{
class MaClasseA { }
class MaClasseB { }
}
Il est aussi possible de déclarer l’espace de noms pour tous les types d’un fichier en spécifiant dans le fichier l’espace de noms avec étendue de fichier de la manière suivante :
namespace MonEspace;
class MaClasseA { }
class MaClasseB { }
Les deux notations produiront le même résultat à la compilation.
2. Le mot-clé using
Pour accéder à un type, il suffit de préciser son nom dans la hiérarchie d’espace de noms. Ainsi, pour instancier un objet Form, il faudra saisir :
System.Windows.Forms.Form...
Les types de base
Les types de données permettent de stocker des valeurs dans l’application. Les langages .NET étant fortement typés, il n’est pas toujours possible de convertir un type de données en un autre. Les conversions, implicites ou explicites, permettent de convertir les types de données. Cela est possible car tous les types du Framework .NET dérivent du type Object qui est le type de base de tous les autres types.
1. Les types numériques
Les types numériques sont décomposés en deux parties : les entiers et les décimaux. Chacun dispose d’un ensemble de types pour représenter les données de la manière la plus judicieuse en fonction des besoins.
a. Les entiers
Le tableau suivant répertorie les types d’entiers disponibles dans le Framework .NET :
Type .NET |
Nom C# |
Description |
Plage de valeurs |
System.Byte |
byte |
Entier non signé de 8 bits |
De 0 à 255 |
System.Int16 |
short |
Entier signé de 16 bits |
De -32 768 à 32 767 |
System.Int32 |
int |
Entier signé de 32 bits |
De -2 147 483 648 à 2 147 483 647 |
System.Int64 |
long |
Entier signé de 64 bits |
De -9 223 372 036 854 775 808 à 9 223 372 036 854 775 807 |
System.SByte |
sbyte |
Entier signé de 8 bits |
De -128 à 127 |
System.UInt16 |
ushort |
Entier non signé de 16 bits |
De 0 à 65 535 |
System.UInt32 |
uint |
Entier non signé de 32 bits |
De 0 à 4 294 967 295 |
System.UInt64 |
ulong |
Entier non signé de 64 bits |
De 0 à 18 446 744 073 709 551 615 |
Une valeur peut être assignée à un entier avec une notation décimale :
int i = 2; // Notation décimale
La notation hexadécimale peut aussi être utilisée et elle doit être précédée du préfixe 0x :
int i = 0x4B; // Notation hexadécimale équivalente à: i = 75;
La notation binaire est également disponible et elle doit être précédée du préfixe 0b :
int i = 0b1101; // Notation binaire équivalente à: i = 13;
Pour faciliter la lecture du code, le caractère _ peut être utilisé comme séparateur :
int i = 10_000_000; //...
Les constantes et les énumérations
Les constantes sont des variables qui ne peuvent pas être modifiées lors de l’exécution. Elles permettent d’une part d’associer des noms conviviaux à des valeurs fréquemment utilisées dans le code, et d’autre part de centraliser une valeur de manière à ne la modifier qu’une seule fois pour toute l’application. Les énumérations sont un ensemble de constantes facilitant la lisibilité et la maintenance du code.
1. Les constantes
Le mot-clé const permet de définir une constante au sein d’une classe :
class MaClasse
{
const int HeureParJour = 24;
}
Les constantes peuvent être de tout type valeur ou string, elles représentent des valeurs fixes qui ne pourront pas être modifiées en cours d’exécution du programme.
Une constante peut être utilisée dans le code en faisant référence à son nom :
int i = HeureParJour; // i = 24
Suivant son niveau d’accès, une constante peut aussi être utilisée hors de la classe qui la définit et sera appelée en tant que membre statique :
int i = MaClasse.HeureParJour; //...
Les tableaux
Les tableaux permettent de grouper des séries de variables et d’y accéder au moyen d’un index basé sur 0. Les tableaux peuvent avoir une ou plusieurs dimensions.
La déclaration d’un tableau se fait en ajoutant [] au type de données qui seront stockées et son initialisation se fait en indiquant le nombre maximum d’éléments qu’il pourra contenir :
int[] Tab;
Tab = new int[10];
La déclaration et l’initialisation peuvent se faire en une seule instruction :
int[] Tab = new int[10];
Le tableau déclaré dans le code précédent pourra contenir 10 éléments de type int et aura un index compris entre 0 et 9.
Il est possible d’initialiser un tableau sans spécifier de limite maximum mais en spécifiant une série de valeurs. Elles sont disposées entre accolades et séparées par des virgules :
int[] Tab = new int[] { 1, 2, 5, 9, 12 };
Le Framework .NET prend également en charge les tableaux multidimensionnels. Les tableaux rectangulaires sont des tableaux où chacune des lignes possède le même nombre de colonnes :
int[,] Tab = new int[2, 2];
int[,,] Tab = new int[5, 3, 2];
Les tableaux en escalier sont un autre type de tableaux multidimensionnels. À la différence des tableaux rectangulaires, les tableaux en escalier ont des lignes...
Les collections
Une collection est un type spécialisé qui organise et expose des groupes d’objets. À l’image des tableaux, on accède aux membres par un index. La différence est que les collections sont redimensionnables et qu’il est possible d’ajouter et de supprimer des membres lors de l’exécution.
Les collections se trouvent dans l’espace de noms System.Collections. La plus commune des collections est le type ArrayList qui permet d’ajouter et de supprimer dynamiquement des éléments soit à la fin, soit à un index prédéterminé :
ArrayList maCollection = new ArrayList();
maCollection.Add(new object());
maCollection.Insert(0, "ABCD");
La collection de type ArrayList contient des objets de type object. Il est possible d’insérer plusieurs types d’objets différents. Cela implique que, lors de la récupération, l’objet doit être converti explicitement :
string s = (string)maCollection[0];
Le principal intérêt des collections est de pouvoir réaliser une boucle de tous les membres grâce à l’instruction foreach :
foreach (object o in maCollection)
{}
Lorsque vous utilisez cette syntaxe, il faut vous assurer que tous les membres ont le même type que la variable d’itération et si ce n’est pas le cas...
Les directives preprocessor
Les directives preprocessor fournissent au compilateur des informations supplémentaires sur les sections du code. Les plus communes de ces directives sont les directives conditionnelles qui permettent d’inclure ou non certaines sections lors de la compilation.
Les directives sont définies dans les propriétés du projet (menu Projet - Propriétés de SelfMailer...) sous l’onglet Build dans la section Général :
Par défaut, Visual Studio génère deux symboles DEBUG et TRACE en mode de compilation Debug et seulement TRACE en mode Release. Il est possible de ne pas générer ces symboles en ne les spécifiant pas ou d’en ajouter des personnalisés dans le champ Symboles de compilation conditionnelle.
L’exemple suivant teste si la constante DEBUG est définie afin d’exécuter le code :
class MaClasse
{
int i;
public void MaMethode()
{
#if DEBUG
MessageBox.Show("i = " + i.ToString());
#endif
}
}
Si la constante DEBUG est définie au moment de la compilation, le code permettant d’afficher une boîte de dialogue avec la valeur de la variable i sera compilé....