Recherche…


Introduction

Un enum peut dériver de l'un des types suivants: octet, sbyte, short, ushort, int, uint, long, ulong. La valeur par défaut est int et peut être modifiée en spécifiant le type dans la définition enum:

énumération publique Jour de la semaine: octet {lundi = 1, mardi = 2, mercredi = 3, jeudi = 4, vendredi = 5}

Ceci est utile lorsque P / Invoking au code natif, mappage aux sources de données et circonstances similaires. En général, le int par défaut doit être utilisé, car la plupart des développeurs s'attendent à ce qu'un énum soit un int.

Syntaxe

  • Enum Colors {Rouge, Vert, Bleu} // Déclaration Enum
  • enum Couleurs: octet {Rouge, Vert, Bleu} // Déclaration avec un type spécifique
  • Enum Couleurs {Rouge = 23, Vert = 45, Bleu = 12} // Déclaration avec des valeurs définies
  • Colors.Red // Accéder à un élément d'un Enum
  • int value = (int) Colors.Red // Récupère la valeur int d'un élément enum
  • Couleurs color = (Couleurs) intValue // Récupère un élément enum depuis int

Remarques

Un Enum (abréviation de "type énuméré") est un type constitué d'un ensemble de constantes nommées, représentées par un identificateur spécifique au type.

Les énumérations sont les plus utiles pour représenter des concepts ayant un nombre (généralement faible) de valeurs discrètes possibles. Par exemple, ils peuvent être utilisés pour représenter un jour de la semaine ou un mois de l'année. Ils peuvent également être utilisés comme indicateurs pouvant être combinés ou vérifiés à l'aide d'opérations binaires.

Obtenez toutes les valeurs de membres d'un enum

enum MyEnum
{
    One,
    Two,
    Three
}

foreach(MyEnum e in Enum.GetValues(typeof(MyEnum)))
    Console.WriteLine(e);

Cela va imprimer:

One
Two
Three

Enum comme drapeaux

Le FlagsAttribute peut être appliqué à un enum modifiant le comportement du ToString() pour correspondre à la nature de l'énumération:

[Flags]
enum MyEnum
{
    //None = 0, can be used but not combined in bitwise operations
    FlagA = 1,
    FlagB = 2,
    FlagC = 4,
    FlagD = 8  
    //you must use powers of two or combinations of powers of two 
    //for bitwise operations to work
}

var twoFlags = MyEnum.FlagA | MyEnum.FlagB;

// This will enumerate all the flags in the variable: "FlagA, FlagB".
Console.WriteLine(twoFlags);

Étant FlagsAttribute que FlagsAttribute s'appuie sur les constantes d'énumération pour avoir deux puissances (ou leurs combinaisons) et que les valeurs d'énumération sont finalement des valeurs numériques, vous êtes limité par la taille du type numérique sous-jacent. Le plus grand type numérique disponible que vous pouvez utiliser est UInt64 , qui vous permet de spécifier 64 constantes enum distinctes (non combinées). Le mot clé enum utilise par défaut le type sous-jacent int , à savoir Int32 . Le compilateur autorisera la déclaration de valeurs supérieures à 32 bits. Ceux-ci se dérouleront sans avertissement et aboutiront à deux ou plusieurs membres de la même valeur. Par conséquent, si un enum est destiné à accueillir un ensemble de bits de plus de 32 indicateurs, vous devez spécifier explicitement un type plus grand:

public enum BigEnum : ulong
{
    BigValue = 1 << 63
}

Bien que les drapeaux ne représentent souvent qu'un seul bit, ils peuvent être combinés en «ensembles» nommés pour une utilisation plus facile.

[Flags]
enum FlagsEnum
{
    None = 0,
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
       
    Default = Option1 | Option3,
    All = Option1 | Option2 | Option3,
}

Pour éviter d'épeler les valeurs décimales des puissances de deux, l' opérateur de décalage à gauche (<<) peut également être utilisé pour déclarer le même enum

[Flags]
enum FlagsEnum
{
    None = 0,
    Option1 = 1 << 0,
    Option2 = 1 << 1,
    Option3 = 1 << 2,
       
    Default = Option1 | Option3,
    All = Option1 | Option2 | Option3,
}

A partir de C # 7.0, les littéraux binaires peuvent aussi être utilisés.

Pour vérifier si la valeur de la variable enum a un certain drapeau, la méthode HasFlag peut être utilisée. Disons que nous avons

[Flags]
enum MyEnum
{
    One = 1,
    Two = 2,
    Three = 4
}

Et une value

var value = MyEnum.One | MyEnum.Two;

Avec HasFlag nous pouvons vérifier si l'un des indicateurs est défini

if(value.HasFlag(MyEnum.One))
    Console.WriteLine("Enum has One");

if(value.HasFlag(MyEnum.Two))
    Console.WriteLine("Enum has Two");

if(value.HasFlag(MyEnum.Three))
    Console.WriteLine("Enum has Three");

Nous pouvons également parcourir toutes les valeurs de enum pour obtenir tous les indicateurs définis

var type = typeof(MyEnum);
var names = Enum.GetNames(type);

foreach (var name in names)
{
    var item = (MyEnum)Enum.Parse(type, name);

    if (value.HasFlag(item))
        Console.WriteLine("Enum has " + name);
}

Ou

foreach(MyEnum flagToCheck in Enum.GetValues(typeof(MyEnum)))
{
    if(value.HasFlag(flagToCheck))
    {
         Console.WriteLine("Enum has " + flagToCheck);
    }
}

Les trois exemples vont imprimer:

Enum has One
Enum has Two

Tester les valeurs d'énumération de style avec la logique binaire

Une valeur d'énumération de style drapeaux doit être testée avec une logique bit par bit car elle ne peut correspondre à aucune valeur unique.

[Flags]
enum FlagsEnum
{
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Option2And3 = Option2 | Option3;

    Default = Option1 | Option3,
}

La valeur Default est en fait une combinaison de deux autres fusionnés avec un OU au niveau du bit. Par conséquent, pour tester la présence d'un indicateur, nous devons utiliser un ET au niveau du bit.

var value = FlagsEnum.Default;

bool isOption2And3Set = (value & FlagsEnum.Option2And3) == FlagsEnum.Option2And3;

Assert.True(isOption2And3Set);

Enum pour enchaîner et revenir

public enum DayOfWeek
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

    
// Enum to string
string thursday = DayOfWeek.Thursday.ToString(); // "Thursday"

string seventhDay = Enum.GetName(typeof(DayOfWeek), 6); // "Saturday"

string monday = Enum.GetName(typeof(DayOfWeek), DayOfWeek.Monday); // "Monday"


// String to enum (.NET 4.0+ only - see below for alternative syntax for earlier .NET versions)
DayOfWeek tuesday;
Enum.TryParse("Tuesday", out tuesday); // DayOfWeek.Tuesday

DayOfWeek sunday;
bool matchFound1 = Enum.TryParse("SUNDAY", out sunday); // Returns false (case-sensitive match)

DayOfWeek wednesday;
bool matchFound2 = Enum.TryParse("WEDNESDAY", true, out wednesday); // Returns true; DayOfWeek.Wednesday (case-insensitive match)


// String to enum (all .NET versions)
DayOfWeek friday = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "Friday"); // DayOfWeek.Friday

DayOfWeek caturday = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "Caturady"); // Thows ArgumentException

// All names of an enum type as strings
string[] weekdays = Enum.GetNames(typeof(DayOfWeek));

Valeur par défaut pour enum == ZERO

La valeur par défaut d'un enum est zéro . Si une énumération ne définit pas un élément avec une valeur de zéro, sa valeur par défaut sera zéro.

public class Program
{        
    enum EnumExample
    {
        one = 1,
        two = 2
    }
    
    public void Main()
    {              
        var e = default(EnumExample);
        
        if (e == EnumExample.one)
            Console.WriteLine("defaults to one");
        else
            Console.WriteLine("Unknown");    
    }    
}

Exemple: https://dotnetfiddle.net/l5Rwie

Bases d'énum

De MSDN :

Un type d'énumération (également appelé énumération ou énumération) fournit un moyen efficace de définir un ensemble de constantes intégrales nommées pouvant être affectées à une variable .

Essentiellement, un enum est un type qui n'autorise qu'un ensemble d'options finies et chaque option correspond à un nombre. Par défaut, ces nombres augmentent dans l'ordre dans lequel les valeurs sont déclarées, à partir de zéro. Par exemple, on pourrait déclarer une énumération pour les jours de la semaine:

public enum Day
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

Cette énumération pourrait être utilisée comme ceci:

// Define variables with values corresponding to specific days
Day myFavoriteDay = Day.Friday;
Day myLeastFavoriteDay = Day.Monday;

// Get the int that corresponds to myFavoriteDay
// Friday is number 4
int myFavoriteDayIndex = (int)myFavoriteDay;

// Get the day that represents number 5
Day dayFive = (Day)5;

Par défaut, le type sous-jacent de chaque élément de l' enum est int , mais les byte , byte , sbyte short , ushort , uint , long et ulong peuvent également être utilisés. Si vous utilisez un type autre que int , vous devez spécifier le type en utilisant deux-points après le nom enum:

public enum Day : byte 
{
    // same as before 
}

Les nombres après le nom sont maintenant des octets au lieu d'entiers. Vous pouvez obtenir le type sous-jacent de l'énumération comme suit:

Enum.GetUnderlyingType(typeof(Days)));

Sortie:

System.Byte

Démo: violon .NET

Manipulation binaire utilisant des énumérations

FlagsAttribute doit être utilisé chaque fois que l'énumérateur représente une collection d'indicateurs, plutôt qu'une valeur unique. La valeur numérique attribuée à chaque valeur enum aide lors de la manipulation des énumérations à l'aide d'opérateurs binaires.

Exemple 1: Avec [Drapeaux]

[Flags]
enum Colors
{
    Red=1,
    Blue=2,
    Green=4,
    Yellow=8
}

var color = Colors.Red | Colors.Blue;
Console.WriteLine(color.ToString());

imprime rouge, bleu

Exemple 2: sans [drapeaux]

enum Colors
{
    Red=1,
    Blue=2,
    Green=4,
    Yellow=8
}
var color = Colors.Red | Colors.Blue;
Console.WriteLine(color.ToString());

imprime 3

Utiliser la notation pour les drapeaux

L'opérateur de décalage à gauche ( << ) peut être utilisé dans les déclarations d'énumération afin de s'assurer que chaque indicateur a exactement 1 en représentation binaire, comme le devraient les indicateurs.

Cela aide également à améliorer la lisibilité des grands enums avec beaucoup de drapeaux.

[Flags]
public enum MyEnum 
{
    None  = 0,
    Flag1 = 1 << 0,
    Flag2 = 1 << 1,
    Flag3 = 1 << 2,
    Flag4 = 1 << 3,
    Flag5 = 1 << 4,
    ...
    Flag31 = 1 << 30
}

Il est maintenant évident que MyEnum contient que des indicateurs corrects et non des éléments désordonnés comme Flag30 = 1073741822 (ou 111111111111111111111111111110 en binaire), ce qui est inapproprié.

Ajout d'informations de description supplémentaires à une valeur enum

Dans certains cas, vous pouvez vouloir ajouter une description supplémentaire à une valeur enum, par exemple lorsque la valeur enum elle-même est moins lisible que ce que vous pourriez souhaiter afficher pour l'utilisateur. Dans ce cas, vous pouvez utiliser la classe System.ComponentModel.DescriptionAttribute .

Par exemple:

public enum PossibleResults
{
    [Description("Success")]
    OK = 1,
    [Description("File not found")]
    FileNotFound = 2,
    [Description("Access denied")]
    AccessDenied = 3
}

Maintenant, si vous souhaitez renvoyer la description d'une valeur d'énumération spécifique, vous pouvez effectuer les opérations suivantes:

public static string GetDescriptionAttribute(PossibleResults result)
{
        return ((DescriptionAttribute)Attribute.GetCustomAttribute((result.GetType().GetField(result.ToString())), typeof(DescriptionAttribute))).Description;
}

static void Main(string[] args)
{
    PossibleResults result = PossibleResults.FileNotFound;
    Console.WriteLine(result); // Prints "FileNotFound"
    Console.WriteLine(GetDescriptionAttribute(result)); // Prints "File not found"
}

Cela peut également être facilement transformé en une méthode d'extension pour toutes les énumérations:

static class EnumExtensions
{
    public static string GetDescription(this Enum enumValue)
    {
        return ((DescriptionAttribute)Attribute.GetCustomAttribute((enumValue.GetType().GetField(enumValue.ToString())), typeof(DescriptionAttribute))).Description;
    }
}

Et ensuite facilement utilisé comme ceci: Console.WriteLine(result.GetDescription());

Ajouter et supprimer des valeurs de l'énumération marquée

Ce code consiste à ajouter et à supprimer une valeur d'une instance d'énumération marquée:

[Flags]
public enum MyEnum
{
    Flag1 = 1 << 0,
    Flag2 = 1 << 1,
    Flag3 = 1 << 2
}

var value = MyEnum.Flag1;

// set additional value
value |= MyEnum.Flag2;  //value is now Flag1, Flag2
value |= MyEnum.Flag3;  //value is now Flag1, Flag2, Flag3

// remove flag
value &= ~MyEnum.Flag2; //value is now Flag1, Flag3    

Enums peuvent avoir des valeurs inattendues

Comme un enum peut être converti en et à partir de son type intégral sous-jacent, la valeur peut tomber en dehors de la plage de valeurs donnée dans la définition du type enum.

Bien que le type DaysOfWeek ci-dessous DaysOfWeek que 7 valeurs définies, il peut toujours contenir une valeur int .

public enum DaysOfWeek
{
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thursday = 4,
    Friday = 5,
    Saturday = 6,
    Sunday = 7
}

DaysOfWeek d = (DaysOfWeek)31;
Console.WriteLine(d); // prints 31

DaysOFWeek s = DaysOfWeek.Sunday;
s++; // No error

Il n'y a actuellement aucun moyen de définir une énumération qui n'a pas ce comportement.

Toutefois, les valeurs d'énumération non définies peuvent être détectées à l'aide de la méthode Enum.IsDefined . Par exemple,

DaysOfWeek d = (DaysOfWeek)31;
Console.WriteLine(Enum.IsDefined(typeof(DaysOfWeek),d)); // prints False


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow