Ce qui suit se veut un bref survol des énumérations en C#. Une énumération, vue de manière superficielle, est un type dont les valeurs acceptables font partie d'une série finie de valeurs symboliques auxquelles des valeurs entières sont associées, ce qui peut remplacer une écriture plus fastidieuse :
Avec constantes | Avec énumérations |
---|---|
|
|
Par défaut, le premier symbole d'une énumération correspond à la valeur entière zéro, et les symboles subséquents ont les valeurs successives (1, 2, 3, ...), mais il est possible de contrôler plus finement cette attribution de valeurs si désiré :
enum Fruits
{
Tomate = -1, // oui, c'est un fruit
Orange, // vaut 0
Pomme, // vaut 1
Citron = 10,
Cerise, // vaut 11
Lime = 10 // vaut aussi 10... Légal, mais pas nécessairement une bonne idée
}
La classe Test ci-dessous définit un type énuméré Jour pouvant représenter un ensemble de valeurs symboliques correspondant aux jours de la semaine. Il est possible d'utiliser des variables et des paramètres de type Jour, tout comme il est possible de comparer des instances de Jour entre elles.
Le passage d'un entier à un Jour et la transformation d'un Jour en texte sont présentés dans la méthode Main().
using System;
using System.Collections;
const int NB_JOURS = 7;
Jour j = (Jour) new Random().Next(NB_JOURS);
string nom = Enum.GetName(typeof(Jour), j);
if (EstFérié(j))
Console.WriteLine($"{nom} est férié");
else
Console.WriteLine($"{nom} n'est pas férié");
static bool EstFérié(Jour j) =>
j == Jour.Samedi || j == Jour.Dimanche;
enum Jour { Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi }
Notez qu'il est possible de convertir une valeur hors bornes en une énumération, ce qui peut surprendre celles et ceux qui ne s'y attendent pas. Ainsi, ceci :
using System;
for(int i = 0; i != 10; ++i)
Console.WriteLine($"{{(Jour)i}} vaut {i}");
enum Jour { Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi }
Comme c'est le cas avec plusieurs autres langages, les enum de C# utilisent des types entiers à titre de substrat, et le substrat par défaut est int. Il est cependant possible d'écrire des enum qui reposent sur des types entiers autres que int. Par exemple :
enum Jour : byte { Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi }
Ceci peut permettre de contrôler la taille des valeurs énumérées en mémoire et la plage de valeurs possibles. En particulier, pour les gens qui utilisent des enum pour représenter des masques dans le but de réaliser des opérations bit à bit, ce contrôle du subtrat permet d'obtenir des masques de plus de 32 bits.
Il arrive que l'on souhaite utiliser enum avec des char, pour ne pas avoir à écrire une série de constantes comme :
const char MUR = '#';
const char VIDE = ' ';
// etc.
C'est évidemment (!) possible, parce que char est (techniquement, car il y a un piège ici; voir plus bas) un type entier et que les enum utilisent des types entiers à titre de substrat. Ainsi, ceci fonctionne très bien :
using System;
Guidis guidi = Guidis.Mur;
Console.WriteLine(guidi);
Console.WriteLine((char)guidi);
Console.WriteLine((int)guidi);
Console.WriteLine((Guidis)'#');
guidi = Guidis.Vide;
Console.WriteLine((int)guidi);
// si vous voulez parcourir diverses valeurs, vous pouvez envisager un tableau
Guidis[] options = new[] { Guidis.Mur, Guidis.Vide };
enum Guidis { Mur = '#', Vide = ' ' } // etc.
Notez toutefois que C# n'est pas tout à fait cohérent sur ce point. En effet, s'il est possible d'écrire des enum qui reposent sur des types entiers autres que int, il n'est pas possible d'utiliser un char comme substrat (même si on peut mettre des char dans les entiers qui composent un enum, comme démontré ici, comme on peut d'ailleurs mettre un char dans un int).
Quelques liens pour enrichir le propos.