Imaginez que vous êtes le responsable de la communication d'un théâtre à la mode. Votre principale mission consiste à gérer les fauteuils du premier rang, c'est-à-dire à veiller à ce que les proches des artistes et autres VIP obtiennent les meilleures places.
Si vous n'aviez qu' à gérer deux invitations pour l'artiste principal, vous pourriez vous contenter d'utiliser deux variables contenant le nom de l'invité. Le code C# ressemblerait à ceci :
// Déclarer une variable pour chaque invité du premier rang
string invitePremierRang1;
string invitePremierRang2;
Ensuite, lorsque l'artiste vous fournirait les informations, vous n'auriez qu'à attribuer un nom à chaque variable. Par exemple :
// Attribuer le nom des invités
invitePremierRang1 = "Mary Poppins";
invitePremierRang2 = "Jane Banks";
Si le premier rang compte 30 sièges, vous devriez donc déclarer 30 variables une par une. Ne serait-il pas plus simple d'utiliser une seule variable qui contiendrait toutes ces informations ?
Vous avez de la chance ! C# offre une structure de données capable de contenir un nombre fixe de valeurs d'un même type. Cette structure s'appelle un array (ou tableau). Voyons quand et comment l'utiliser.
Utilisez un array pour stocker un nombre fixe d'éléments
Un array est une liste ordonnée et numérotée d'éléments du même type. Chaque élément est associé à un numéro appelé index. L'indexation commence à 0 (pas 1 !), ce qui signifie que le premier élément est associé à l’index 0, le deuxième à 1, etc.
Pour déclarer un array, il faut utiliser la même syntaxe que pour n'importe quelle variable. Vous devez ainsi fournir :
le type des éléments que l'array contiendra, suivi de
[]
;le nom de la variable qui doit expliciter l'objectif de l'array.
Par exemple, pour stocker le nombre de tasses de café que vous buvez chaque jour de la semaine, vous pouvez déclarer un array d'entiers avec la syntaxe suivante :
// Déclarer la variable
int[] tassesDeCafeParJourDeLaSemaine;
Créez ensuite l'array avec sept emplacements (les sept jours de la semaine), et initialisez-le :
// Créer l'array et l'affecter à la variable
tassesDeCafeParJourDeLaSemaine = new int[7];
Lorsque l'array est créé, chaque élément est initialisé avec la valeur par défaut du type de l'array. Dans le cas d'un array de type int
, cette valeur est 0.
Vous pouvez aussi déclarer et créer un array en une seule ligne. Voici comment procéder pour un array de trois int
:
Pour en revenir à notre gestion hebdomadaire du café, maintenant que l'array est créé, vous pouvez effectuer deux opérations :
Accéder à une valeur à un index donné.
Définir une nouvelle valeur à un index donné.
Dans les deux cas, vous utilisez le nom de la variable suivi de [
, la valeur de l'index, puis ]
.
Par exemple, si vous buvez trois cafés le cinquième jour de la semaine, vous pouvez écrire :
// Affecter la valeur 3 au cinquième jour de la semaine
// Il s'agit de l'index 4, puisque le premier index est 0
tassesDeCafeParJourDeLaSemaine[4] = 3;
Pour afficher le nombre de cafés que vous buvez le premier jour de la semaine, vous pouvez écrire l'instruction suivante :
//Afficher le nombre de cafés bus le premier jour de la semaine
Console.WriteLine(tassesDeCafeParJourDeLaSemaine[0]);
Enfin, si vous souhaitez définir toutes les valeurs en même temps, vous pouvez également :
définir toutes les valeurs au moment de la création de l'array ;
ou utiliser une boucle qui définit chaque valeur, une par une.
Nous aborderons les boucles dans la prochaine partie du cours. Pour l'instant, créons un nouvel array et affectons-le à la variable tassesDeCafeParJourDeLaSemaine
:
//Créer un nouvel array avec toutes les valeurs et l'affecter à notre variable
tassesDeCafeParJourDeLaSemaine = new int[] {6,2,3,7,3,4,1};
Testez par vous-même !
Et le premier rang de notre salle de théâtre ? Eh bien, vous n'avez qu'à créer un array de chaînes de caractères comportant autant d'éléments que votre premier rang compte de sièges. Vous pouvez soit ajouter tous vos invités au moment de la création, soit les ajouter individuellement en utilisant la syntaxe []
.
Prêt à coder ? Pour accéder à l’exercice, suivez ce lien.
Si vous voulez aller plus loin et gérer tous les rangs de votre théâtre, vous pouvez utiliser des arrays multidimensionnels. Imaginons que votre théâtre contienne 30 rangs de 12 places chacun. Voici comment créer un array et attribuer une valeur au sixième siège du dixième rang :
// Créer un array multidimensionnel pour gérer tous les rangs d'un théâtre
string[,] mesSieges = new string[30,12];
// Rang 10, siège 6. N'oubliez pas que l'index commence à 0 !
mesSieges[9,5] = "James Logan";
Les arrays sont mutables, efficaces et parfaits si vous gérez un nombre fixe d'éléments.
Que signifie « mutable » ?
En termes simples, les objets mutables peuvent être modifiés après leur création, alors que les objets immuables ne le peuvent pas. Par exemple, une chaîne de caractères ( string
) est immuable.
string nom = "jean";
nom = "simon";
Console.WriteLine(nom); //-> simon
La réponse à l'exemple ci-dessus est « simon ».
Une minute ! N'a-t-on pas dit que les chaînes de caractères sont immuables ? Pourquoi la valeur de nom a-t-elle pu être modifiée ?
C'est vrai. En réalité, le compilateur a créé un nouvel objet de chaîne de caractères pour nom, puis lui a affecté la valeur « simon ». Voyez ce qui se passe lorsque vous essayez de modifier le contenu d'une variable de chaîne de caractères :
string nom = "jean";
// Mettre le premier caractère en majuscule
nom[0] = "J"; //->ERREUR. Impossible d'assigner la propriété ou l'indexeur 'string.this[int]' -- il est en lecture seule.
Console.WriteLine(nom);
Vous obtenez l'erreur « Impossible d'assigner la propriété ou l'indexeur 'string.this[int]' -- il est en lecture seule ». C'est la preuve qu'une variable de chaîne de caractères est immuable ; elle ne peut pas changer.
Comme nous l'avons dit précédemment, les arrays sont en revanche mutables.
int[] monArray = new int[] { 1,2,3,4,5,6 };
monArray[4] = 7;
Console.WriteLine(monArray[4]); //-> 7
L'array étant mutable, vous pouvez le modifier sans que le compilateur crée un nouvel objet array.
À mesure que vous apprendrez le C#, vous saisirez mieux le concept des objets mutables et immuables, car ces deux caractéristiques ont un impact sur les performances et la gestion de la mémoire de vos applications.
Utilisez des listes si le nombre d'éléments n'est pas fixe
Les arrays sont vraiment pratiques, mais ils ont leurs limites :
ils ont une taille fixe ;
vous ne pouvez modifier que les valeurs existantes.
Imaginons que vous vouliez classer des animaux du plus mignon au moins mignon, et que vous commenciez par un petit array composé de quatre éléments : renard, hibou, koala et loutre. Supposons maintenant que vous vouliez ajouter un écureuil et le mettre entre le renard et le hibou.
Avec un array, vous ne pouvez pas insérer d’élément supplémentaire. Vous pouvez seulement remplacer des éléments. Vous ne pouvez pas non plus ajouter votre écureuil à la fin de l'array. Pour cela, il faudrait créer un tout nouvel array de cinq emplacements au lieu de quatre. Puis, vous devriez y ajouter une nouvelle fois tous vos éléments à la main. Plutôt long et pénible, non ?
C'est ici qu'entrent en jeu les listes ordonnées ! Comme elles sont mutables, vous pouvez modifier leur contenu et leur nombre d'éléments. Après les restrictions des arrays, cela peut sembler magique ! ✨
Entre autres choses, avec les listes, vous pouvez :
accéder à chaque élément via son index ;
ajouter un nouvel élément à la fin de votre liste ;
insérer un nouvel élément à un index spécifique ;
supprimer un élément à un index spécifique.
Très utile ! En C#, il existe plusieurs classes qui utilisent des listes. Vous pouvez même créer la vôtre ! L'important est que la classe que vous sélectionnez utilise l'interface IList
.
Dans la suite de ce chapitre, nous utiliserons la classe List
, qui est la plus courante. Voyons comment cela fonctionne en pratique !
Créez une liste et ajoutez-y des éléments
Pour créer une liste, vous devez :
Déclarer une variable avec l'interface de type
IList
. Cela signifie que vous pouvez affecter à la variable n'importe quel objet qui implémente l'interfaceIList
, y compris la classeList
.Initialiser la variable avec une expression commençant par le mot-clé new, qui crée une instance de la classe List.
Vous pouvez le faire en une seule ligne avec la syntaxe suivante :
La déclaration a lieu avant l'opérateur d'affectation
=
. Tout d'abord, vous avez le type, qui estList
. Dans cet exemple, vous ne pourrez enregistrer que des nombres entiers.La création en tant que telle a lieu avec l'expression
new List<int>()
. L'objet initialisé est affecté à la variablemaListe
.
Mais qu'en est-il des éléments que nous voulons mettre dans notre liste ?
Très bonne question ! Pour ajouter des éléments dans une liste, vous pouvez utiliser une seule instruction, comme ceci :
IList<int> maListe = new List<int>{1, 2, 3, 4, 5, 6};
Vous pouvez aussi les ajouter un par un comme suit :
IList<int> maListe = new List<int>();
maListe.Add(7); //-> [7]
maListe.Add(5); //-> [7,5]
La première instruction crée une liste vide appelée
maListe
.Vous ajoutez ensuite un premier élément avec l'instruction
maListe.Add(7)
.Enfin, l'instruction
maListe.Add(5)
ajoute un entier de valeur de 5 et l'ajoute à la liste, à l'index 1.
À quoi correspond donc la partie .Add()
? En C#, ajouter, modifier ou supprimer des éléments nécessite l'utilisation d'une méthode et vous l'avez deviné, .Add()
en est une ! À ce stade, tout ce que vous avez besoin de savoir sur les méthodes, c'est qu'elles vous permettent de faire des choses. 😎
Dans le cas de l'interface IList
, la classe List
implémente trois méthodes très pratiques :
Add
pour ajouter un nouvel élément à la fin d'une liste. Ici, vous devez fournir un nouvel élément.Insert
pour insérer un nouvel élément à une position donnée, en spécifiant l'index avant la valeur. Par exemple,maListe.Insert(1,12)
insère un entier avec la valeur 12 à la position 1, et déplace la valeur antérieure à la position 2, et ainsi de suite.RemoveAt
pour supprimer un élément existant sur un index spécifique. Ici, vous devez fournir l'index de l'élément à supprimer. Si vous n'avez plus besoin du premier élément, vous pouvez le retirer de la position 0. Cela déplacera le deuxième élément initial de la position 1 à la position 0, le troisième de la position 2 à la position 1, et ainsi de suite.
Bien, voyons ce que cela donne concrètement. Voici la syntaxe C# pour ce qui précède :
IList<int> maListe = new List<int>(); // -> []
maListe.Add(7); // -> [7]
maListe.Add(5); //-> [7, 5]
maListe.Insert(1,12); //-> [7, 12, 5]
maListe.RemoveAt(1); // Suppression du 12 -> [7, 5]
Décortiquons tout ça, d'accord ?
Nous retrouvons la même opération que précédemment : ajouter 7, puis 5 à la liste.
Nous ajoutons ensuite la valeur
12
à l'index 1. La valeur antérieure de l'index 1 est donc déplacée vers l'index 2.Pour finir, avec
.RemoveAt()
, nous demandons à notre liste de supprimer toute valeur trouvée à l'index 1. Cela veut dire que nous lui demandons de supprimer 12.
Au final, il nous reste une liste de deux entiers : 7 et 5. Imaginez faire cela avec des arrays de taille fixe !
Suivez le nombre d'éléments dans votre liste
Il existe une propriété très intéressante, Count
, qui vous permet d'obtenir le nombre d'éléments dans une liste :
IList<int> maListe = new List<int>();
maListe.Add(1); // ->[1]
maListe.Add(2); //-> [1,2]
Console.WriteLine(maListe.Count); // -> 2
Cette propriété facilite grandement le suivi des éléments de votre liste.
La propriété Count
est largement utilisée, notamment lorsque vous avez besoin de faire une boucle sur une liste. Nous aborderons les boucles dans le chapitre 3 de la prochaine partie.
Testez par vous-même !
Prêt à coder ? Pour accéder à l’exercice, suivez ce lien.
Choisissez les ensembles pour les collections non ordonnées
Un ensemble (ou « set ») est une collection d'éléments uniques non ordonnés. Vous les utiliserez lorsque l'ordre des éléments n'a pas d'importance, par exemple pour une liste d'ingrédients d'une recette. 🥑🌶🥕🌽🍅🍳
Déclarez des ensembles
Comme pour les listes, C# utilise différentes classes pour gérer les ensembles. Nous allons nous concentrer sur la classe la plus communément utilisée, HashSet
.
Penchons-nous sur le code C# ci-dessous :
Comme vous pouvez le voir, le processus est similaire à celui des listes
. Vous déclarez d'abord la variable avec l'interface ISet
, puis vous l'initialisez avec une instance de la classe concrète HashSet
.
Manipulez les éléments d'un ensemble
Les opérations les plus courantes à réaliser avec des ensembles sont les suivantes :
ajouter un nouvel élément avec une nouvelle clé ;
supprimer un élément pour une clé spécifique ;
compter le nombre d'éléments de l'ensemble.
Comment retrouver un élément ?
Les ensembles étant des collections non ordonnées, il n'existe pas de moyens de le faire simplement, comme vous avez pu le voir jusqu'à présent. Cette opération est possible, mais vous découvrirez comment la réaliser une fois que vous aurez approfondi vos connaissances en programmation.
Pour ajouter un nouvel élément, utilisez Add()
:
ISet<string> ingredients = new HashSet<string>();
ingredients.Add("oeufs");
ingredients.Add("sucre");
ingredients.Add("beurre");
ingredients.Add("sel");
Comme les ensembles sont non ordonnés, il n'est pas nécessaire d'ajouter les éléments spécifiquement à la fin de l'ensemble ou à un endroit en particulier. Utilisez tout simplement Add()
!
Pour supprimer un élément, on utilise Remove()
:
ISet<string> ingredients = new HashSet<string>();
ingredients.Add("sel"); // Ajouter du sel dans la liste des ingrédients
ingredients.Remove("sel"); // Supprimer le sel de la liste des ingrédients
L'important, c'est de renseigner l'élément exact à supprimer. Dans notre exemple, il s'agit de se débarrasser du « sel ».
Comme pour les listes, vous devez utiliser la propriété Count
pour obtenir le nombre d'éléments dans un ensemble :
Console.WriteLine(ingredients.Count);
Testez par vous-même !
Prêt à coder ? Pour accéder à l’exercice, suivez ce lien.
Découvrez les dictionnaires
Pour résumer la vidéo, un dictionnaire est une liste d'éléments organisés en fonction d'une clé. Cette clé est un terme spécifique que vous recherchez pour trouver sa définition ou sa valeur. C'est ce qu'on appelle une association « CLÉ <> VALEUR ».
Par exemple, si vous voulez lister les noms de vos amis et leur âge respectif, les dictionnaires sont la collection à utiliser :
Toutes les clés d’un dictionnaire doivent être uniques. On peut faire une analogie avec une chaise : une seule personne peut s'asseoir sur une chaise à un moment donné.
Déclarez des dictionnaires
Comme pour les listes et les ensembles, C# propose plusieurs classes pour manipuler les dictionnaires. Chacune de ces classes utilise l'interface IDictionary
. Pour en savoir plus, vous pouvez consulter la documentation complète sur le site Web des tutoriels C# de Microsoft.
Dans cette section, nous utiliserons la classe la plus courante : Dictionary
. Voici le code permettant de déclarer et d'initialiser une instance de cette classe :
La différence principale avec les listes et les ensembles réside dans le fait que vous paramétrez votre dictionnaire avec deux éléments, en utilisant la syntaxe <string, int>.
string
est le type de la clé.int
est le type de la valeur.
Pour ajouter des éléments à votre dictionnaire, utilisez la méthode monDictionnaire.Add()
. Entre parenthèses, indiquez d'abord la clé, puis la valeur :
// Les âges de mes amis
monDictionnaire.Add("Jennifer", 34);
monDictionnaire.Add("Livia", 28);
monDictionnaire.Add("Paul", 31);
Console.WriteLine(monDictionnaire["Jennifer"]); // -> 34
Dans la dernière ligne, nous avons demandé au programme d'afficher la valeur de la clé Jennifer. Dans ce code :
la méthode
Console.WriteLine()
affiche le résultat d'une expression fournie entre parenthèses ;l'expression réelle,
monDictionnaire["Jennifer"]
, renvoie la valeur identifiée par la clé « Jennifer », qui est stockée dans la variablemonDictionnaire
.
Lorsque vous utilisez des chaînes comme clés, n'oubliez pas que ces clés sont sensibles à la casse. Ainsi, « Jennifer » et « jennifer » sont deux clés différentes associées à deux éléments différents dans un dictionnaire. Par exemple :
monDictionnaire.Add("Jennifer", 34);
monDictionnaire.Add("Livia", 28);
monDictionnaire.Add("Paul", 31);
monDictionnaire.Add("jennifer", 21);
Console.WriteLine(monDictionnaire["Jennifer"]); // -> 34
Console.WriteLine(monDictionnaire["jennifer"]); // -> 21
Pour éviter de telles situations, une astuce consiste à utiliser des constantes pour spécifier les clés une fois et les réutiliser ensuite dans tout le code :
// Définir des clés en tant que constantes
const string cleJennifer = "Jennifer";
const string cleLivia = "Livia";
const string clePaul = "Paul";
// Utiliser des constantes comme clés
monDictionnaire.Add(cleJennifer, 34);
monDictionnaire.Add(cleLivia, 28);
monDictionnaire.Add(clePaul, 31);
// Accéder à un élément
Console.WriteLine(monDictionnaire[cleJennifer]); // -> 34
Comme vous pouvez le voir, il faut utiliser le mot-clé const
pour indiquer que vous avez besoin que vos chaînes soient des constantes et non des variables. Cela est très utile dans la mesure où vous avez la certitude de conserver vos clés pour toujours, sans risquer de perdre de données en changeant les chaînes par erreur !
Quelques précisions au sujet des clés
Si le type le plus couramment utilisé est string
, les clés en C# peuvent être de différents types. Par exemple int
:
matin.Add(1, "réveil");
Les règles applicables aux dictionnaires sont les mêmes que pour les types de variables simples et les arrays : leur type ne peut pas être modifié. Toutes les valeurs et toutes les clés doivent être du même type :
monDictionnaire.Add(cleJennifer, 34);
monDictionnaire.Add(cleLivia, 28); // Ok
monDictionnaire.Add("Paul", "Designer"); // Erreur
Manipulez les éléments d'un dictionnaire
Les opérations les plus courantes que vous pouvez effectuer avec les dictionnaires sont les suivantes :
accéder à la valeur d'un élément par sa clé ;
ajouter un nouvel élément avec une nouvelle clé et une valeur ;
supprimer un élément pour une clé spécifique.
Supposons que nous ayons un dictionnaire comportant des noms de personnes et leur emploi. Appelons-le « professions ».
Vous pouvez ajouter une valeur avec la méthode
Add()
et deux arguments : la clé et la valeur.Pour accéder à une valeur, précisez la clé entre crochets
[]
après le nom du dictionnaire. On parle alors d'indexeur.
Jetons un coup d'œil à cela :
professions.Add("Jennifer", "Cheffe d'entreprise");
Console.WriteLine(professions["Jennifer"]); // -> Cheffe d'entreprise
Vous pouvez également modifier un élément en réutilisant une clé avec l'indexeur :
professions.Add("Jennifer", "Cheffe d'entreprise");
Console.WriteLine(professions["Jennifer"]); // -> Cheffe d'entreprise
professions["Jennifer"] = "Programmeuse";
Console.WriteLine(professions["Jennifer"]); // -> Programmeuse
Enfin, pour supprimer un élément, vous pouvez utiliser la méthode Remove()
avec la clé de l'élément que vous voulez supprimer :
professions.Remove("Jennifer");
Comptez les éléments
Les dictionnaires, comme les listes et les ensembles, utilisent la propriété Count
pour déterminer le nombre d'éléments :
Console.WriteLine(professions.Count);
Testez par vous-même !
Prêt à coder ? Pour accéder à l’exercice, suivez ce lien.
En résumé
Ce chapitre vous a appris les bases de la manipulation des conteneurs qui stockent plusieurs éléments d'un certain type de données :
Array (conteneurs de taille fixe) : les éléments d'un array sont indexés à partir de 0 et sont accessibles à l'aide de cet index. Le nombre d'éléments ne peut pas être modifié.
Listes (listes ordonnées) : les éléments d'une liste se comportent comme un array. Le nombre d'éléments peut évoluer en ajoutant et en supprimant des éléments.
Ensembles (listes non ordonnées) : les éléments d'un ensemble sont stockés sans ordre particulier. Vous pouvez y accéder en les énumérant.
Dictionnaires : les éléments d'un dictionnaire sont organisés par paires clé-valeur, et sont accessibles à l'aide d'une clé.
Les actions les plus courantes effectuées avec les collections sont :
Accéder à un élément.
Ajouter un nouvel élément.
Supprimer un élément.
Modifier un élément.
Compter tous les éléments.
Énumérer tous les éléments.
La collection que vous choisissez dépend de la tâche à accomplir. Une fois que vous aurez progressé dans votre carrière, vous saurez identifier le type le plus approprié à utiliser.