Enums
Déclaration
Ensemble de constantes nommées dont la valeur est de type entier : → Contrairement au C♯, il faut définir la valeur de tous les membres de l'enum :
type ColorN =
| Red = 1
| Green = 2
| Blue = 3☝️ Noter la différence de syntaxe avec un type union "enum-like" (Style "enum") :
type Color = Red | Green | BlueType sous-jacent
Contrairement au C♯, il n'y a pas de type sous-jacent par défaut en F♯.
Le type sous-jacent est défini au moyen des littéraux définissant les valeurs des membres :
1,2,3→int1uy,2uy,3uy→byteEtc. - cf. Literals
Corolaire : il faut utiliser le même type pour tous les membres, sinon cela ne compile pas !
type ColorN =
| Red = 1
| Green = 2
| Blue = 3uy
// 💥 ~~~~~~~~~~~
// Cette expression était censée avoir le type `int`
// mais elle a ici le type `byte`Char
Le type char peut être utilisé comme type sous-jacent :
Casse
Autre différence avec les types union, les membres peuvent être en camelCase :
Usage
⚠️ Contrairement aux unions, l'emploi d'un membre (a.k.a littéral) d'enum est forcément qualifié
Cast via helpers int et enum (mais pas char) :
Pattern matching
⚠️ Contrairement aux unions, le pattern matching n'est pas exhaustif
Valeurs
On peut utiliser la méthode System.Enum.GetValues() pour obtenir la liste des membres d'une enum. Par contre, le type de retour est faiblement typé : Array (tableau non générique).
→ Il suffit d'encapsuler cette méthode dans une fonction helper telle que :
💡 Voir également Extras
Flags
Même principe qu'en C♯ où l'on choisit comme valeurs des multiples de 2 afin de pouvoir les combiner :
💡 Notes :
L'attribut
System.FlagsAttributeest facultatif mais permet d'avoir un code plus explicite. En outre, il améliore le rendu des combinaisons de flags : dans l'exemple précédent, la valeur affichée depermissionsestRead, Write. Sans l'attributFlags, cela aurait afficher3.Opérateur OU binaire
|||(|en C♯) pour combiner des flags
💡 Astuce : utiliser la notation binaire pour la valeur des flags :
Combinaisons
En C♯, l'on peut directement combiner des flags, comme ReadWrite et All ci-dessous :
Ce n'est pas possible en F♯ mais 2 alternatives sont possibles :
1) Procéder manuellement aux combinaisons binaires : ce n'est pas dur à faire mais cela nuit à la visibilité car cela demande un peu de réflexion pour retrouver les flags initiaux. On notera aussi que ces combinaisons font partie intégrante de l'enum.
2) Utiliser un module compagnon : pour rendre les combinaisons explicites dans le code mais non reconnues / recombinées par le compilateur.
☝ Note : la méthode HasFlag a un comportement différent selon l'option utilisée. C'est mis en valeur dans l'exemple ci-dessous définissant les 2 helpers Enum.values déjà vu plus haut et Enum.flags qui décompose une valeur d'enum en ses flags élémentaires.
Enum vs Union
Type sous-jacent
Entières ou char
Quelconques
Qualification
Obligatoire
Qu'en cas de conflit
Matching exhaustif
❌ Non
✅ Oui
PascalCase
✅ Oui
✅ Oui
camelCase
✅ Oui
❌ Non
☝ Recommandation :
Préférer une Union dans la majorité des cas
Choisir une Enum pour :
Interop .NET
Besoin de lier des données de type
int
Conversion
enum<'enum> : permet de convertir une valeur entière en l'enum 'enum spécifiée
int permet la conversion inverse pour récupérer la valeur sous-jacente d'un membre d'une enum
Char enum
Pour les enums dont le type sous-jacent est char, les fonctions enum, int et char ne marchent pas :
Il faut alors utiliser le module LanguagePrimitives :
Extras
Le package NuGet FSharpx.Extras comporte un module Enum proposant ces helpers :
parse<'enum>: string -> 'enumtryParse<'enum>: string -> 'enum optiongetValues<'enum>: unit -> 'enum seq
Mis à jour
Ce contenu vous a-t-il été utile ?