Zoeken…


Invoering

Een opsomming kan afkomstig zijn van een van de volgende typen: byte, sbyte, kort, ushort, int, uint, lang, ulong. De standaardwaarde is int en kan worden gewijzigd door het type in de enum-definitie op te geven:

public enum Weekdag: byte {maandag = 1, dinsdag = 2, woensdag = 3, donderdag = 4, vrijdag = 5}

Dit is handig wanneer u P / uitnodigt naar native code, toewijzingen naar gegevensbronnen en vergelijkbare omstandigheden. Over het algemeen moet de standaardint worden gebruikt, omdat de meeste ontwikkelaars verwachten dat een opsomming een int is.

Syntaxis

  • enum Colors {Rood, Groen, Blauw} // Enum-aangifte
  • enum Colors: byte {Rood, Groen, Blauw} // Verklaring met specifiek type
  • enum Colors {Rood = 23, Groen = 45, Blauw = 12} // Verklaring met gedefinieerde waarden
  • Colors.Red // Toegang tot een element van een Enum
  • int value = (int) Colors.Red // Krijg de int-waarde van een enum-element
  • Colors color = (Colors) intValue // Haal een enum-element op van int

Opmerkingen

Een Enum (afkorting voor "genummerd type") is een type dat bestaat uit een set benoemde constanten, vertegenwoordigd door een typespecifieke identifier.

Enums zijn het meest nuttig voor het weergeven van concepten met een (meestal klein) aantal mogelijke discrete waarden. Ze kunnen bijvoorbeeld worden gebruikt om een dag van de week of een maand van het jaar weer te geven. Ze kunnen ook worden gebruikt als vlaggen die kunnen worden gecombineerd of gecontroleerd met behulp van bitsgewijze bewerkingen.

Verkrijg alle ledenwaarden van een opsomming

enum MyEnum
{
    One,
    Two,
    Three
}

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

Dit zal afdrukken:

One
Two
Three

Enum als vlaggen

Het FlagsAttribute kan worden toegepast op een opsomming die het gedrag van de ToString() wijzigt om overeen te komen met de aard van de opsomming:

[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);

Omdat FlagsAttribute afhankelijk is van de opsommingsconstanten als machten van twee (of hun combinaties) en opsommingswaarden uiteindelijk numerieke waarden zijn, wordt u beperkt door de grootte van het onderliggende numerieke type. Het grootste beschikbare numerieke type dat u kunt gebruiken, is UInt64 , waarmee u 64 afzonderlijke (niet-gecombineerde) UInt64 kunt opgeven. Het enum trefwoord is standaard ingesteld op het onderliggende type int , dat is Int32 . De compiler staat de declaratie van waarden breder dan 32 bit toe. Die zullen zonder waarschuwing rondlopen en resulteren in twee of meer leden van dezelfde waarde. Daarom, als een opsomming bedoeld is om een bitset van meer dan 32 vlaggen op te nemen, moet u expliciet een groter type opgeven:

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

Hoewel vlaggen vaak maar één bit zijn, kunnen ze worden gecombineerd tot benoemde "sets" voor eenvoudiger gebruik.

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

Om te voorkomen dat de decimale waarden van machten van twee worden gespeld, kan de operator voor linkse shift (<<) ook worden gebruikt om dezelfde opsomming te declareren

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

Beginnend met C # 7.0 kunnen ook binaire literalen worden gebruikt.

Om te controleren of de waarde van enum-variabele een bepaalde vlag heeft ingesteld, kan de HasFlag methode worden gebruikt. Laten we zeggen dat we dat hebben gedaan

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

En een value

var value = MyEnum.One | MyEnum.Two;

Met HasFlag we controleren of een van de vlaggen is ingesteld

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");

We kunnen ook alle waarden van enum doorlopen om alle ingestelde vlaggen te krijgen

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);
}

Of

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

Alle drie voorbeelden worden afgedrukt:

Enum has One
Enum has Two

Test enum-waarden in vlaggenstijl met bitgewijze logica

Een opsomming in vlaggenstijl moet worden getest met bitsgewijze logica omdat deze mogelijk niet overeenkomt met een enkele waarde.

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

    Default = Option1 | Option3,
}

De Default is in feite een combinatie van twee andere samengevoegd met een bitgerichte OF. Om de aanwezigheid van een vlag te testen, moeten we daarom een beetje bit AND gebruiken.

var value = FlagsEnum.Default;

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

Assert.True(isOption2And3Set);

Tellen naar string en terug

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));

Standaardwaarde voor enum == ZERO

De standaardwaarde voor een opsomming is nul . Als een opsomming geen item met een waarde van nul definieert, is de standaardwaarde nul.

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");    
    }    
}

Voorbeeld: https://dotnetfiddle.net/l5Rwie

Enum basics

Van MSDN :

Een opsommingstype (ook een opsomming of een opsomming genoemd) biedt een efficiënte manier om een set benoemde integrale constanten te definiëren die aan een variabele kunnen worden toegewezen .

In wezen is een opsomming een type dat alleen een set eindige opties toestaat, en elke optie komt overeen met een getal. Standaard worden die getallen groter in de volgorde waarin de waarden worden aangegeven, beginnend bij nul. Je zou bijvoorbeeld een opsomming kunnen geven voor de dagen van de week:

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

Dat opsomming zou als volgt kunnen worden gebruikt:

// 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;

Standaard is het onderliggende type van elk element in het enum int , maar byte , sbyte , short , ushort , uint , long en ulong kunnen ook worden gebruikt. Als u een ander type dan int , moet u het type opgeven met een dubbele punt achter de enumnaam:

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

De cijfers achter de naam zijn nu bytes in plaats van gehele getallen. Je zou het onderliggende type van de opsomming als volgt kunnen krijgen:

Enum.GetUnderlyingType(typeof(Days)));

Output:

System.Byte

Demo: .NET viool

Bitwise Manipulation met behulp van enums

Het FlagsAttribute moet worden gebruikt wanneer de opsombare een verzameling vlaggen vertegenwoordigt, in plaats van een enkele waarde. De numerieke waarde die aan elke opsommingswaarde wordt toegewezen, helpt bij het manipuleren van opsommingen met bitsgewijze operatoren.

Voorbeeld 1: Met [Vlaggen]

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

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

print rood, blauw

Voorbeeld 2: Zonder [Vlaggen]

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

afdrukken 3

<< notatie gebruiken voor vlaggen

De linker-shift-operator ( << ) kan worden gebruikt in vlaggenmeldingen om ervoor te zorgen dat elke vlag exact één 1 in binaire weergave, zoals vlaggen zouden moeten.

Dit helpt ook om de leesbaarheid van grote enums met veel vlaggen te verbeteren.

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

Het is nu duidelijk dat MyEnum alleen juiste vlaggen bevat en geen rommelige dingen zoals Flag30 = 1073741822 (of 111111111111111111111111111110 in binair) wat ongepast is.

Aanvullende beschrijvingsinformatie toevoegen aan een opsommingswaarde

In sommige gevallen wilt u misschien een extra beschrijving toevoegen aan een opsommingswaarde, bijvoorbeeld wanneer de opsommingswaarde zelf minder leesbaar is dan wat u aan de gebruiker wilt weergeven. In dergelijke gevallen kunt u de klasse System.ComponentModel.DescriptionAttribute .

Bijvoorbeeld:

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

Als u nu de beschrijving van een specifieke opsommingswaarde wilt retourneren, kunt u het volgende doen:

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"
}

Dit kan ook eenvoudig worden omgezet in een uitbreidingsmethode voor alle enums:

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

En dan gemakkelijk als volgt gebruikt: Console.WriteLine(result.GetDescription());

Waarden toevoegen en verwijderen uit gemarkeerde opsomming

Deze code is om een waarde toe te voegen en te verwijderen uit een gemarkeerde enum-instantie:

[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 kunnen onverwachte waarden hebben

Aangezien een opsomming van en naar het onderliggende integrale type kan worden geworpen, kan de waarde buiten het bereik vallen van waarden die zijn opgegeven in de definitie van het opsommingstype.

Hoewel het onderstaande enum-type DaysOfWeek slechts 7 gedefinieerde waarden heeft, kan het nog steeds elke int waarde bevatten.

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

Er is momenteel geen manier om een opsomming te definiëren die dit gedrag niet heeft.

Niet-gedefinieerde opsommingswaarden kunnen echter worden gedetecteerd met de methode Enum.IsDefined . Bijvoorbeeld,

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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow