Classe System.Enum

Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.

Une énumération est un ensemble de constantes nommées dont le type sous-jacent est n’importe quel type intégral. Si aucun type sous-jacent n’est explicitement déclaré, Int32 il est utilisé. Enum est la classe de base pour toutes les énumérations dans .NET. Les types d’énumération sont définis par les enum mot clé en C#, la Enumconstruction ...End Enum en Visual Basic et la type mot clé en F#.

Enum fournit des méthodes pour comparer des instances de cette classe, convertir la valeur d’une instance en sa représentation sous forme de chaîne, convertir la représentation sous forme de chaîne d’un nombre en instance de cette classe et créer une instance d’une énumération et d’une valeur spécifiées.

Vous pouvez également traiter une énumération comme un champ de bits. Pour plus d’informations, consultez les membres non exclusifs et la section attribut Indicateurs et FlagsAttribute.

Créer un type d’énumération

Les langages de programmation fournissent généralement une syntaxe pour déclarer une énumération qui se compose d’un ensemble de constantes nommées et de leurs valeurs. L’exemple suivant illustre la syntaxe utilisée par C#, F# et Visual Basic pour définir une énumération. Il crée une énumération nommée ArrivalStatus qui a trois membres : ArrivalStatus.Early, ArrivalStatus.OnTimeet ArrivalStatus.Late. Notez que dans tous les cas, l’énumération n’hérite pas explicitement de Enum; la relation d’héritage est gérée implicitement par le compilateur.

public enum ArrivalStatus { Unknown=-3, Late=-1, OnTime=0, Early=1 };
type ArrivalStatus =
    | Late = -1
    | OnTime = 0
    | Early = 1
Public Enum ArrivalStatus1 As Integer
    Late = -1
    OnTime = 0
    Early = 1
End Enum

Avertissement

Vous ne devez jamais créer un type d’énumération dont le type sous-jacent n’est pas intégral ou Char. Bien que vous puissiez créer un tel type d’énumération à l’aide de la réflexion, les appels de méthode qui utilisent le type résultant ne sont pas fiables et peuvent également lever des exceptions supplémentaires.

Instancier un type d’énumération

Vous pouvez instancier un type d’énumération tout comme vous instanciez tout autre type valeur : en déclarant une variable et en lui affectant l’une des constantes de l’énumération. L’exemple suivant instancie une ArrivalStatus valeur dont la valeur est ArrivalStatus.OnTime.

public class Example
{
   public static void Main()
   {
      ArrivalStatus status = ArrivalStatus.OnTime;
      Console.WriteLine("Arrival Status: {0} ({0:D})", status);
   }
}
// The example displays the following output:
//       Arrival Status: OnTime (0)
let status = ArrivalStatus.OnTime
printfn $"Arrival Status: {status} ({status:D})"
// The example displays the following output:
//       Arrival Status: OnTime (0)
Public Module Example1
    Public Sub Main()
        Dim status As ArrivalStatus1 = ArrivalStatus1.OnTime
        Console.WriteLine("Arrival Status: {0} ({0:D})", status)
    End Sub
End Module
' The example displays the following output:
'        Arrival Status: OnTime (0)

Vous pouvez également instancier une valeur d’énumération de la manière suivante :

  • En utilisant les fonctionnalités d’un langage de programmation particulier pour effectuer un cast (comme en C#) ou convertir (comme en Visual Basic) une valeur entière en valeur d’énumération. L’exemple suivant crée un ArrivalStatus objet dont la valeur est ArrivalStatus.Early de cette façon.

    ArrivalStatus status2 = (ArrivalStatus)1;
    Console.WriteLine("Arrival Status: {0} ({0:D})", status2);
    // The example displays the following output:
    //       Arrival Status: Early (1)
    
    let status2 = enum<ArrivalStatus> 1
    printfn $"Arrival Status: {status2} ({status2:D})"
    // The example displays the following output:
    //       Arrival Status: Early (1)
    
    Dim status2 As ArrivalStatus2 = CType(1, ArrivalStatus2)
    Console.WriteLine("Arrival Status: {0} ({0:D})", status2)
    ' The example displays the following output:
    '       Arrival Status: Early (1)
    
  • En appelant son constructeur sans paramètre implicite. Comme l’illustre l’exemple suivant, dans ce cas, la valeur sous-jacente de l’instance d’énumération est 0. Toutefois, il ne s’agit pas nécessairement de la valeur d’une constante valide dans l’énumération.

    ArrivalStatus status1 = new ArrivalStatus();
    Console.WriteLine("Arrival Status: {0} ({0:D})", status1);
    // The example displays the following output:
    //       Arrival Status: OnTime (0)
    
    let status1 = ArrivalStatus()
    printfn $"Arrival Status: {status1} ({status1:D})"
    // The example displays the following output:
    //       Arrival Status: OnTime (0)
    
    Dim status1 As New ArrivalStatus2()
    Console.WriteLine("Arrival Status: {0} ({0:D})", status1)
    ' The example displays the following output:
    '        Arrival Status: OnTime (0)
    
  • En appelant la ou TryParse la Parse méthode pour analyser une chaîne qui contient le nom d’une constante dans l’énumération. Pour plus d’informations, consultez la section Valeurs d’énumération d’analyse.

  • En appelant la ToObject méthode pour convertir une valeur intégrale en type d’énumération. Pour plus d’informations, consultez la section Effectuer des conversions .

Bonnes pratiques d’énumération

Nous vous recommandons d’utiliser les meilleures pratiques suivantes lorsque vous définissez des types d’énumération :

  • Si vous n’avez pas défini de membre d’énumération dont la valeur est 0, envisagez de créer une None constante énumérée. Par défaut, la mémoire utilisée pour l’énumération est initialisée à zéro par le Common Language Runtime. Par conséquent, si vous ne définissez pas de constante dont la valeur est égale à zéro, l’énumération contient une valeur illégale lors de sa création.

  • S’il existe un cas par défaut évident que votre application doit représenter, envisagez d’utiliser une constante énumérée dont la valeur est égale à zéro pour la représenter. S’il n’existe aucun cas par défaut, envisagez d’utiliser une constante énumérée dont la valeur est égale à zéro pour spécifier le cas qui n’est représenté par aucune des autres constantes énumérées.

  • Ne spécifiez pas de constantes énumérées réservées pour une utilisation ultérieure.

  • Lorsque vous définissez une méthode ou une propriété qui prend une constante énumérée comme valeur, envisagez de valider la valeur. La raison est que vous pouvez convertir une valeur numérique en type d’énumération même si cette valeur numérique n’est pas définie dans l’énumération.

Des bonnes pratiques supplémentaires pour les types d’énumération dont les constantes sont des champs de bits sont répertoriées dans les membres non exclusifs et la section attribut Indicateurs.

Effectuer des opérations avec des énumérations

Vous ne pouvez pas définir de nouvelles méthodes lorsque vous créez une énumération. Toutefois, un type d’énumération hérite d’un ensemble complet de méthodes statiques et d’instance de la Enum classe. Les sections suivantes interrogent la plupart de ces méthodes, en plus de plusieurs autres méthodes couramment utilisées lors de l’utilisation de valeurs d’énumération.

Effectuer des conversions

Vous pouvez effectuer une conversion entre un membre d’énumération et son type sous-jacent à l’aide d’un cast (en C# et F#) ou d’un opérateur de conversion (en Visual Basic). En F#, la enum fonction est également utilisée. L’exemple suivant utilise des opérateurs de conversion ou de conversion pour effectuer des conversions d’un entier vers une valeur d’énumération et d’une valeur d’énumération en entier.

int value3 = 2;
ArrivalStatus status3 = (ArrivalStatus)value3;

int value4 = (int)status3;
let value3 = 2
let status3 = enum<ArrivalStatus> value3

let value4 = int status3
Dim value3 As Integer = 2
Dim status3 As ArrivalStatus2 = CType(value3, ArrivalStatus2)

Dim value4 As Integer = CInt(status3)

La Enum classe inclut également une ToObject méthode qui convertit une valeur de tout type intégral en valeur d’énumération. L’exemple suivant utilise la ToObject(Type, Int32) méthode pour convertir une Int32 valeur en valeur ArrivalStatus . Notez que, étant donné que le ToObject retour d’une valeur de type Object, l’utilisation d’un opérateur de conversion ou de conversion peut toujours être nécessaire pour convertir l’objet en type d’énumération.

int number = -1;
ArrivalStatus arrived = (ArrivalStatus)ArrivalStatus.ToObject(typeof(ArrivalStatus), number);
let number = -1
let arrived = ArrivalStatus.ToObject(typeof<ArrivalStatus>, number) :?> ArrivalStatus
Dim number As Integer = -1
Dim arrived As ArrivalStatus2 = CType(ArrivalStatus2.ToObject(GetType(ArrivalStatus2), number), ArrivalStatus2)

Lors de la conversion d’un entier en valeur d’énumération, il est possible d’affecter une valeur qui n’est pas réellement membre de l’énumération. Pour éviter cela, vous pouvez passer l’entier à la méthode avant d’effectuer IsDefined la conversion. L’exemple suivant utilise cette méthode pour déterminer si les éléments d’un tableau de valeurs entières peuvent être convertis en ArrivalStatus valeurs.

using System;

public class Example3
{
    public static void Main()
    {
        int[] values = { -3, -1, 0, 1, 5, Int32.MaxValue };
        foreach (var value in values)
        {
            ArrivalStatus status;
            if (Enum.IsDefined(typeof(ArrivalStatus), value))
                status = (ArrivalStatus)value;
            else
                status = ArrivalStatus.Unknown;
            Console.WriteLine("Converted {0:N0} to {1}", value, status);
        }
    }
}
// The example displays the following output:
//       Converted -3 to Unknown
//       Converted -1 to Late
//       Converted 0 to OnTime
//       Converted 1 to Early
//       Converted 5 to Unknown
//       Converted 2,147,483,647 to Unknown
open System

type ArrivalStatus =
    | Unknown = -3
    | Late = -1
    | OnTime = 0
    | Early = 1

let values = [ -3; -1; 0; 1; 5; Int32.MaxValue ]
for value in values do
    let status =
        if Enum.IsDefined(typeof<ArrivalStatus>, value) then
            enum value
        else
            ArrivalStatus.Unknown
    printfn $"Converted {value:N0} to {status}"
// The example displays the following output:
//       Converted -3 to Unknown
//       Converted -1 to Late
//       Converted 0 to OnTime
//       Converted 1 to Early
//       Converted 5 to Unknown
//       Converted 2,147,483,647 to Unknown
Public Enum ArrivalStatus4 As Integer
    Unknown = -3
    Late = -1
    OnTime = 0
    Early = 1
End Enum

Module Example4
    Public Sub Main()
        Dim values() As Integer = {-3, -1, 0, 1, 5, Int32.MaxValue}
        For Each value In values
            Dim status As ArrivalStatus4
            If [Enum].IsDefined(GetType(ArrivalStatus4), value) Then
                status = CType(value, ArrivalStatus4)
            Else
                status = ArrivalStatus4.Unknown
            End If
            Console.WriteLine("Converted {0:N0} to {1}", value, status)
        Next
    End Sub
End Module
' The example displays the following output:
'       Converted -3 to Unknown
'       Converted -1 to Late
'       Converted 0 to OnTime
'       Converted 1 to Early
'       Converted 5 to Unknown
'       Converted 2,147,483,647 to Unknown

Bien que la Enum classe fournit des implémentations d’interface explicites de l’interface IConvertible pour la conversion d’une valeur d’énumération en type intégral, vous devez utiliser les méthodes de la Convert classe, telles que ToInt32, pour effectuer ces conversions. L’exemple suivant montre comment utiliser la GetUnderlyingType méthode ainsi que la Convert.ChangeType méthode pour convertir une valeur d’énumération en son type sous-jacent. Notez que cet exemple ne nécessite pas que le type sous-jacent de l’énumération soit connu au moment de la compilation.

ArrivalStatus status = ArrivalStatus.Early;
var number = Convert.ChangeType(status, Enum.GetUnderlyingType(typeof(ArrivalStatus)));
Console.WriteLine("Converted {0} to {1}", status, number);
// The example displays the following output:
//       Converted Early to 1
let status = ArrivalStatus.Early
let number = Convert.ChangeType(status, Enum.GetUnderlyingType typeof<ArrivalStatus>)
printfn $"Converted {status} to {number}"
// The example displays the following output:
//       Converted Early to 1
Dim status As ArrivalStatus5 = ArrivalStatus5.Early
Dim number = Convert.ChangeType(status, [Enum].GetUnderlyingType(GetType(ArrivalStatus5)))
Console.WriteLine("Converted {0} to {1}", status, number)
' The example displays the following output:
'       Converted Early to 1

Analyser les valeurs d’énumération

Les Parse méthodes et TryParse les méthodes vous permettent de convertir la représentation sous forme de chaîne d’une valeur d’énumération en cette valeur. La représentation sous-jacente peut être le nom ou la valeur sous-jacente d’une constante d’énumération. Notez que les méthodes d’analyse convertissent correctement les représentations sous-jacentes de chaînes de nombres qui ne sont pas membres d’une énumération particulière si les chaînes peuvent être converties en valeur du type sous-jacent de l’énumération. Pour éviter cela, la IsDefined méthode peut être appelée pour s’assurer que le résultat de la méthode d’analyse est une valeur d’énumération valide. L’exemple illustre cette approche et illustre les appels aux méthodes et Enum.TryParse<TEnum>(String, TEnum) aux Parse(Type, String) méthodes. Notez que la méthode d’analyse non générique retourne un objet que vous devrez peut-être convertir (en C# et F#) ou convertir (en Visual Basic) en type d’énumération approprié.

string number = "-1";
string name = "Early";

try
{
    ArrivalStatus status1 = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), number);
    if (!(Enum.IsDefined(typeof(ArrivalStatus), status1)))
        status1 = ArrivalStatus.Unknown;
    Console.WriteLine("Converted '{0}' to {1}", number, status1);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
                      number);
}

ArrivalStatus status2;
if (Enum.TryParse<ArrivalStatus>(name, out status2))
{
    if (!(Enum.IsDefined(typeof(ArrivalStatus), status2)))
        status2 = ArrivalStatus.Unknown;
    Console.WriteLine("Converted '{0}' to {1}", name, status2);
}
else
{
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus value.",
                      number);
}
// The example displays the following output:
//       Converted '-1' to Late
//       Converted 'Early' to Early
let number = "-1"
let name = "Early"

try
    let status1 = Enum.Parse(typeof<ArrivalStatus>, number) :?> ArrivalStatus
    let status1 =
        if not (Enum.IsDefined(typeof<ArrivalStatus>, status1) ) then
            ArrivalStatus.Unknown
        else 
            status1
        
    printfn $"Converted '{number}' to {status1}"
with :? FormatException ->
    printfn $"Unable to convert '{number}' to an ArrivalStatus value."

match Enum.TryParse<ArrivalStatus> name with
| true, status2 ->
    let status2 = 
        if not (Enum.IsDefined(typeof<ArrivalStatus>, status2) ) then
            ArrivalStatus.Unknown
        else 
            status2
    printfn $"Converted '{name}' to {status2}"
| _ ->
    printfn $"Unable to convert '{number}' to an ArrivalStatus value."
// The example displays the following output:
//       Converted '-1' to Late
//       Converted 'Early' to Early
Dim number As String = "-1"
Dim name As String = "Early"
Dim invalid As String = "32"

Try
    Dim status1 As ArrivalStatus8 = CType([Enum].Parse(GetType(ArrivalStatus8), number), ArrivalStatus8)
    If Not [Enum].IsDefined(GetType(ArrivalStatus8), status1) Then status1 = ArrivalStatus8.Unknown
    Console.WriteLine("Converted '{0}' to {1}", number, status1)
Catch e As FormatException
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.",
                   number)
End Try

Dim status2 As ArrivalStatus8
If [Enum].TryParse(Of ArrivalStatus8)(name, status2) Then
    If Not [Enum].IsDefined(GetType(ArrivalStatus8), status2) Then status2 = ArrivalStatus8.Unknown
    Console.WriteLine("Converted '{0}' to {1}", name, status2)
Else
    Console.WriteLine("Unable to convert '{0}' to an ArrivalStatus8 value.",
                   number)
End If
' The example displays the following output:
'       Converted '-1' to Late
'       Converted 'Early' to Early

Mettre en forme les valeurs d’énumération

Vous pouvez convertir des valeurs d’énumération en leurs représentations sous forme de chaîne en appelant la méthode statique Format , ainsi que les surcharges de la méthode d’instance ToString . Vous pouvez utiliser une chaîne de format pour contrôler la façon précise dont une valeur d’énumération est représentée sous forme de chaîne. Pour plus d’informations, consultez Chaînes de format d’énumération. L’exemple suivant utilise chacune des chaînes de format d’énumération prises en charge (« G » ou « g », « D » ou « d », « X » ou « x » et « F » ou « f » ) pour convertir un membre de l’énumération ArrivalStatus en ses représentations sous forme de chaîne.

string[] formats = { "G", "F", "D", "X" };
ArrivalStatus status = ArrivalStatus.Late;
foreach (var fmt in formats)
    Console.WriteLine(status.ToString(fmt));

// The example displays the following output:
//       Late
//       Late
//       -1
//       FFFFFFFF
let formats = [ "G"; "F"; "D"; "X" ]
let status = ArrivalStatus.Late
for fmt in formats do
    printfn $"{status.ToString fmt}"

// The example displays the following output:
//       Late
//       Late
//       -1
//       FFFFFFFF
Dim formats() As String = {"G", "F", "D", "X"}
Dim status As ArrivalStatus6 = ArrivalStatus6.Late
For Each fmt As String In formats
    Console.WriteLine(status.ToString(fmt))
Next
' The example displays the following output:
'       Late
'       Late
'       -1
'       FFFFFFFF

Itérer des membres d’énumération

Le Enum type n’implémente pas la ou IEnumerable<T> l’interfaceIEnumerable, ce qui vous permet d’itérer les membres d’une collection à l’aide d’une foreach construction (en C#), for..in (en F#) ou For Each (en Visual Basic). Toutefois, vous pouvez énumérer les membres de deux façons.

  • Vous pouvez appeler la GetNames méthode pour récupérer un tableau de chaînes contenant les noms des membres d’énumération. Ensuite, pour chaque élément du tableau de chaînes, vous pouvez appeler la méthode pour convertir la Parse chaîne en sa valeur d’énumération équivalente. L'exemple suivant illustre cette approche.

    string[] names = Enum.GetNames(typeof(ArrivalStatus));
    Console.WriteLine("Members of {0}:", typeof(ArrivalStatus).Name);
    Array.Sort(names);
    foreach (var name in names)
    {
        ArrivalStatus status = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), name);
        Console.WriteLine("   {0} ({0:D})", status);
    }
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          Early (1)
    //          Late (-1)
    //          OnTime (0)
    //          Unknown (-3)
    
    let names = Enum.GetNames typeof<ArrivalStatus>
    printfn $"Members of {nameof ArrivalStatus}:"
    let names = Array.sort names
    for name in names do
        let status = Enum.Parse(typeof<ArrivalStatus>, name) :?> ArrivalStatus
        printfn $"   {status} ({status:D})"
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          Early (1)
    //          Late (-1)
    //          OnTime (0)
    //          Unknown (-3)
    
    Dim names() As String = [Enum].GetNames(GetType(ArrivalStatus7))
    Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name)
    Array.Sort(names)
    For Each name In names
        Dim status As ArrivalStatus7 = CType([Enum].Parse(GetType(ArrivalStatus7), name),
                                   ArrivalStatus7)
        Console.WriteLine("   {0} ({0:D})", status)
    Next
    ' The example displays the following output:
    '       Members of ArrivalStatus7:
    '          Early (1)
    '          Late (-1)
    '          OnTime (0)
    '          Unknown (-3)
    
  • Vous pouvez appeler la GetValues méthode pour récupérer un tableau qui contient les valeurs sous-jacentes dans l’énumération. Ensuite, pour chaque élément du tableau, vous pouvez appeler la méthode pour convertir l’entier ToObject en sa valeur d’énumération équivalente. L'exemple suivant illustre cette approche.

    var values = Enum.GetValues(typeof(ArrivalStatus));
    Console.WriteLine("Members of {0}:", typeof(ArrivalStatus).Name);
    foreach (ArrivalStatus status in values)
    {
        Console.WriteLine("   {0} ({0:D})", status);
    }
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          OnTime (0)
    //          Early (1)
    //          Unknown (-3)
    //          Late (-1)
    
    let values = Enum.GetValues typeof<ArrivalStatus>
    printfn $"Members of {nameof ArrivalStatus}:"
    for status in values do
        printfn $"   {status} ({status:D})"
    // The example displays the following output:
    //       Members of ArrivalStatus:
    //          OnTime (0)
    //          Early (1)
    //          Unknown (-3)
    //          Late (-1)
    
    Dim values = [Enum].GetValues(GetType(ArrivalStatus7))
    Console.WriteLine("Members of {0}:", GetType(ArrivalStatus7).Name)
    For Each value In values
        Dim status As ArrivalStatus7 = CType([Enum].ToObject(GetType(ArrivalStatus7), value),
                                         ArrivalStatus7)
        Console.WriteLine("   {0} ({0:D})", status)
    Next
    ' The example displays the following output:
    '       Members of ArrivalStatus7:
    '          OnTime (0)
    '          Early (1)
    '          Unknown (-3)
    '          Late (-1)
    

Membres non exclusifs et attribut Flags

L’une des utilisations courantes d’une énumération consiste à représenter un ensemble de valeurs mutuellement exclusives. Par exemple, une ArrivalStatus instance peut avoir une valeur de Early, OnTimeou Late. Il n’est pas logique que la valeur d’une ArrivalStatus instance reflète plusieurs constantes d’énumération.

Dans d’autres cas, toutefois, la valeur d’un objet d’énumération peut inclure plusieurs membres d’énumération, et chaque membre représente un champ de bits dans la valeur d’énumération. L’attribut FlagsAttribute peut être utilisé pour indiquer que l’énumération se compose de champs de bits. Par exemple, une énumération nommée Pets peut être utilisée pour indiquer les types d’animaux domestiques dans un foyer. Elle peut être définie comme suit.

[Flags]
public enum Pets
{
    None = 0, Dog = 1, Cat = 2, Bird = 4, Rodent = 8,
    Reptile = 16, Other = 32
};
[<Flags>] 
type Pets =
    | None = 0
    | Dog = 1
    | Cat = 2
    | Bird = 4
    | Rodent = 8
    | Reptile = 16
    | Other = 32
<Flags> Public Enum Pets As Integer
   None = 0
   Dog = 1
   Cat = 2
   Bird = 4
   Rodent = 8
   Reptile = 16
   Other = 32
End Enum

L’énumération Pets peut ensuite être utilisée comme indiqué dans l’exemple suivant.

Pets familyPets = Pets.Dog | Pets.Cat;
Console.WriteLine("Pets: {0:G} ({0:D})", familyPets);
// The example displays the following output:
//       Pets: Dog, Cat (3)
let familyPets = Pets.Dog ||| Pets.Cat
printfn $"Pets: {familyPets:G} ({familyPets:D})"
// The example displays the following output:
//       Pets: Dog, Cat (3)
Dim familyPets As Pets = Pets.Dog Or Pets.Cat
Console.WriteLine("Pets: {0:G} ({0:D})", familyPets)
' The example displays the following output:
'       Pets: Dog, Cat (3)

Les meilleures pratiques suivantes doivent être utilisées lors de la définition d’une énumération au niveau du bit et de l’application de l’attribut FlagsAttribute .

  • Utilisez l’attribut FlagsAttribute personnalisé pour une énumération uniquement si une opération au niveau du bit (AND, OR, EXCLUSIVE OR) doit être effectuée sur une valeur numérique.

  • Définissez les constantes d’énumération en puissances de deux, autrement dit, 1, 2, 4, 8, et ainsi de suite. Cela signifie que les indicateurs individuels dans les constantes d’énumération combinées ne se chevauchent pas.

  • Envisagez de créer une constante énumérée pour les combinaisons d’indicateurs couramment utilisées. Par exemple, si vous avez une énumération utilisée pour les opérations d’E/S de fichier qui contient les constantes Read = 1 énumérées et Write = 2, envisagez de créer la constante ReadWrite = Read OR Writeénumérée, qui combine les indicateurs et Write les Read indicateurs. En outre, l’opération OR au niveau du bit utilisée pour combiner les indicateurs peut être considérée comme un concept avancé dans certaines circonstances qui ne doivent pas être nécessaires pour des tâches simples.

  • Soyez prudent si vous définissez un nombre négatif comme constante énumérée d’indicateurs, car de nombreuses positions d’indicateur peuvent être définies sur 1, ce qui peut rendre votre code déroutant et encourager les erreurs de codage.

  • Un moyen pratique de tester si un indicateur est défini dans une valeur numérique consiste à appeler la méthode d’instance HasFlag , comme illustré dans l’exemple suivant.

    Pets familyPets = Pets.Dog | Pets.Cat;
    if (familyPets.HasFlag(Pets.Dog))
        Console.WriteLine("The family has a dog.");
    // The example displays the following output:
    //       The family has a dog.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if familyPets.HasFlag Pets.Dog then
        printfn "The family has a dog."
    // The example displays the following output:
    //       The family has a dog.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets.HasFlag(Pets.Dog) Then
        Console.WriteLine("The family has a dog.")
    End If
    ' The example displays the following output:
    '       The family has a dog.
    

    Cela équivaut à effectuer une opération AND au niveau du bit entre la valeur numérique et la constante énumérée de l’indicateur, qui définit tous les bits de la valeur numérique sur zéro qui ne correspondent pas à l’indicateur, puis teste si le résultat de cette opération est égal à la constante énumérée de l’indicateur. L'exemple suivant illustre ce concept.

    Pets familyPets = Pets.Dog | Pets.Cat;
    if ((familyPets & Pets.Dog) == Pets.Dog)
        Console.WriteLine("The family has a dog.");
    // The example displays the following output:
    //       The family has a dog.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if (familyPets &&& Pets.Dog) = Pets.Dog then
        printfn "The family has a dog."
    // The example displays the following output:
    //       The family has a dog.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets And Pets.Dog = Pets.Dog Then
        Console.WriteLine("The family has a dog.")
    End If
    ' The example displays the following output:
    '       The family has a dog.
    
  • Utilisez None le nom de la constante énumérée de l’indicateur dont la valeur est égale à zéro. Vous ne pouvez pas utiliser la None constante énumérée dans une opération AND au niveau du bit pour tester un indicateur, car le résultat est toujours égal à zéro. Toutefois, vous pouvez effectuer une comparaison logique, et non pas au niveau du bit, entre la valeur numérique et la None constante énumérée pour déterminer si les bits de la valeur numérique sont définis. L'exemple suivant illustre ce concept.

    Pets familyPets = Pets.Dog | Pets.Cat;
    if (familyPets == Pets.None)
        Console.WriteLine("The family has no pets.");
    else
        Console.WriteLine("The family has pets.");
    // The example displays the following output:
    //       The family has pets.
    
    let familyPets = Pets.Dog ||| Pets.Cat
    if familyPets = Pets.None then
        printfn "The family has no pets."
    else
        printfn "The family has pets."
    // The example displays the following output:
    //       The family has pets.
    
    Dim familyPets As Pets = Pets.Dog Or Pets.Cat
    If familyPets = Pets.None Then
        Console.WriteLine("The family has no pets.")
    Else
        Console.WriteLine("The family has pets.")
    End If
    ' The example displays the following output:
    '       The family has pets.
    
  • Ne définissez pas une valeur d’énumération uniquement pour miroir l’état de l’énumération proprement dite. Par exemple, ne définissez pas de constante énumérée qui marque simplement la fin de l’énumération. Si vous devez déterminer la dernière valeur de l’énumération, case activée pour cette valeur explicitement. En outre, vous pouvez effectuer une plage case activée pour la première et la dernière constante énumérée si toutes les valeurs de la plage sont valides.

Ajouter des méthodes d’énumération

Étant donné que les types d’énumération sont définis par des structures de langage, telles que enum (C#) et Enum (Visual Basic), vous ne pouvez pas définir de méthodes personnalisées pour un type d’énumération autre que ces méthodes héritées de la Enum classe. Toutefois, vous pouvez utiliser des méthodes d’extension pour ajouter des fonctionnalités à un type d’énumération particulier.

Dans l’exemple suivant, l’énumération Grades représente les notes qu’un étudiant peut obtenir dans une classe. Une méthode d’extension nommée Passing est ajoutée au type Grades pour que chaque instance de ce type « sache » maintenant si elle représente une note au-dessus de la moyenne. La Extensions classe contient également une variable statique en lecture-écriture qui définit la classe de passage minimale. La valeur de retour de la Passing méthode d’extension reflète la valeur actuelle de cette variable.

using System;

// Define an enumeration to represent student grades.
public enum Grades { F = 0, D = 1, C = 2, B = 3, A = 4 };

// Define an extension method for the Grades enumeration.
public static class Extensions
{
    public static Grades minPassing = Grades.D;

    public static bool Passing(this Grades grade)
    {
        return grade >= minPassing;
    }
}

class Example8
{
    static void Main()
    {
        Grades g1 = Grades.D;
        Grades g2 = Grades.F;
        Console.WriteLine("{0} {1} a passing grade.", g1, g1.Passing() ? "is" : "is not");
        Console.WriteLine("{0} {1} a passing grade.", g2, g2.Passing() ? "is" : "is not");

        Extensions.minPassing = Grades.C;
        Console.WriteLine("\nRaising the bar!\n");
        Console.WriteLine("{0} {1} a passing grade.", g1, g1.Passing() ? "is" : "is not");
        Console.WriteLine("{0} {1} a passing grade.", g2, g2.Passing() ? "is" : "is not");
    }
}
// The exmaple displays the following output:
//       D is a passing grade.
//       F is not a passing grade.
//
//       Raising the bar!
//
//       D is not a passing grade.
//       F is not a passing grade.
open System
open System.Runtime.CompilerServices
// Define an enumeration to represent student grades.
type Grades =
    | F = 0
    | D = 1
    | C = 2
    | B = 3
    | A = 4

let mutable minPassing = Grades.D

// Define an extension method for the Grades enumeration.
[<Extension>]
type Extensions =
    [<Extension>]
    static member Passing(grade) = grade >= minPassing

let g1 = Grades.D
let g2 = Grades.F
printfn $"""{g1} {if g1.Passing() then "is" else "is not"} a passing grade."""
printfn $"""{g2} {if g2.Passing() then "is" else "is not"} a passing grade."""

minPassing <- Grades.C
printfn "\nRaising the bar!\n"
printfn $"""{g1} {if g1.Passing() then "is" else "is not"} a passing grade."""
printfn $"""{g2} {if g2.Passing() then "is" else "is not"} a passing grade."""
// The exmaple displays the following output:
//       D is a passing grade.
//       F is not a passing grade.
//
//       Raising the bar!
//
//       D is not a passing grade.
//       F is not a passing grade.
Imports System.Runtime.CompilerServices

' Define an enumeration to represent student grades.
Public Enum Grades As Integer
   F = 0
   D = 1
   C = 2
   B = 3
   A = 4
End Enum   

' Define an extension method for the Grades enumeration.
Public Module Extensions
  Public minPassing As Grades = Grades.D
 
  <Extension>
  Public Function Passing(grade As Grades) As Boolean
     Return grade >= minPassing
  End Function
End Module

Public Module Example
  Public Sub Main()
      Dim g1 As Grades = Grades.D
      Dim g2 As Grades = Grades.F
      Console.WriteLine("{0} {1} a passing grade.", 
                        g1, If(g1.Passing(), "is", "is not"))
      Console.WriteLine("{0} {1} a passing grade.", 
                        g2, If(g2.Passing(), "is", "is not"))
      Console.WriteLine()
      
      Extensions.minPassing = Grades.C
      Console.WriteLine("Raising the bar!")
      Console.WriteLine()
      Console.WriteLine("{0} {1} a passing grade.", 
                        g1, If(g1.Passing(), "is", "is not"))
      Console.WriteLine("{0} {1} a passing grade.", 
                        g2, If(g2.Passing(), "is", "is not"))
  End Sub
End Module
' The exmaple displays the following output:
'       D is a passing grade.
'       F is not a passing grade.
'       
'       Raising the bar!
'       
'       D is not a passing grade.
'       F is not a passing grade.

Exemples

L’exemple suivant illustre l’utilisation d’une énumération pour représenter des valeurs nommées et une autre énumération pour représenter des champs de bits nommés.

using System;

public class EnumTest {
    enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
    enum BoilingPoints { Celsius = 100, Fahrenheit = 212 };
    [Flags]
    enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };

    public static void Main() {

        Type weekdays = typeof(Days);
        Type boiling = typeof(BoilingPoints);

        Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:");

        foreach ( string s in Enum.GetNames(weekdays) )
            Console.WriteLine( "{0,-11}= {1}", s, Enum.Format( weekdays, Enum.Parse(weekdays, s), "d"));

        Console.WriteLine();
        Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.");
        Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:");

        foreach ( string s in Enum.GetNames(boiling) )
            Console.WriteLine( "{0,-11}= {1}", s, Enum.Format(boiling, Enum.Parse(boiling, s), "d"));

        Colors myColors = Colors.Red | Colors.Blue | Colors.Yellow;
        Console.WriteLine();
        Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors);
    }
}
open System

type Days =
    | Saturday = 0
    | Sunday = 1
    | Monday = 2
    | Tuesday = 3
    | Wednesday = 4
    | Thursday = 5
    | Friday = 6

type BoilingPoints =
    | Celsius = 100
    | Fahrenheit = 212

[<Flags>]
type Colors =
    | Red = 1
    | Green = 2
    | Blue = 4
    | Yellow = 8

let weekdays = typeof<Days>
let boiling = typeof<BoilingPoints>

printfn "The days of the week, and their corresponding values in the Days Enum are:"

for s in Enum.GetNames weekdays do
    printfn $"""{s,-11}= {Enum.Format(weekdays, Enum.Parse(weekdays, s), "d")}"""

printfn "\nEnums can also be created which have values that represent some meaningful amount."
printfn "The BoilingPoints Enum defines the following items, and corresponding values:"

for s in Enum.GetNames boiling do
    printfn $"""{s,-11}= {Enum.Format(boiling, Enum.Parse(boiling, s), "d")}"""

let myColors = Colors.Red ||| Colors.Blue ||| Colors.Yellow
printfn $"\nmyColors holds a combination of colors. Namely: {myColors}"
Public Class EnumTest
    Enum Days
        Saturday
        Sunday
        Monday
        Tuesday
        Wednesday
        Thursday
        Friday
    End Enum 
    
    Enum BoilingPoints
        Celsius = 100
        Fahrenheit = 212
    End Enum 
    
    <Flags()> _
    Enum Colors
        Red = 1
        Green = 2
        Blue = 4
        Yellow = 8
    End Enum 

    Public Shared Sub Main()
        Dim weekdays As Type = GetType(Days)
        Dim boiling As Type = GetType(BoilingPoints)

        Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:")

        Dim s As String
        For Each s In  [Enum].GetNames(weekdays)
            Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(weekdays, [Enum].Parse(weekdays, s), "d"))
        
        Next s
        Console.WriteLine()
        Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.")
        Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:")

        For Each s In  [Enum].GetNames(boiling)
            Console.WriteLine("{0,-11} = {1}", s, [Enum].Format(boiling, [Enum].Parse(boiling, s), "d"))
        Next s

        Dim myColors As Colors = Colors.Red Or Colors.Blue Or Colors.Yellow
        Console.WriteLine()
        Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors)
    End Sub 
End Class