Suche…


Einführung

Eine Enumeration kann von einer der folgenden Arten abgeleitet werden: Byte, Byte, Kurz, Ushort, Int, Uint, Long, Ulong. Der Standardwert ist int und kann durch Angabe des Typs in der Enumendefinition geändert werden:

public enum Wochentag: Byte {Montag = 1, Dienstag = 2, Mittwoch = 3, Donnerstag = 4, Freitag = 5}

Dies ist nützlich, wenn Sie P / Invoke zu nativem Code aufrufen, Datenquellen zuordnen und ähnliche Umstände. Im Allgemeinen sollte der Standardwert int verwendet werden, da die meisten Entwickler davon ausgehen, dass es sich bei der Aufzählung um ein int handelt.

Syntax

  • Aufzählungsfarben {Red, Green, Blue} // Enum-Deklaration
  • enum Farben: Byte {Rot, Grün, Blau} // Deklaration mit spezifischem Typ
  • Aufzählungsfarben {Rot = 23, Grün = 45, Blau = 12} // Deklaration mit definierten Werten
  • Colors.Red // Greifen Sie auf ein Enum-Element zu
  • int value = (int) Colors.Red // Liefert den Int-Wert eines Enumerationselements
  • Colors color = (Colors) intValue // Holen Sie ein Enumerationselement aus int

Bemerkungen

Eine Aufzählung (Abkürzung für "Aufzählungstyp") ist ein Typ, der aus einer Menge benannter Konstanten besteht, die durch einen typspezifischen Bezeichner dargestellt werden.

Aufzählungen sind am nützlichsten, um Konzepte darzustellen, die eine (normalerweise kleine) Anzahl möglicher diskreter Werte haben. Sie können beispielsweise verwendet werden, um einen Wochentag oder einen Monat des Jahres darzustellen. Sie können auch als Flags verwendet werden, die mit bitweisen Operationen kombiniert oder geprüft werden können.

Holen Sie sich alle Mitgliederwerte einer Aufzählung

enum MyEnum
{
    One,
    Two,
    Three
}

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

Dies wird drucken:

One
Two
Three

Aufzählung als Flaggen

Das FlagsAttribute kann auf ein Enum angewendet werden, das das Verhalten von ToString() , um es an die Art des ToString() :

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

Da FlagsAttribute die Aufzählungskonstanten Potenzen von zwei (oder deren Kombinationen) sind und die Aufzählungswerte letztendlich numerische Werte sind, sind Sie durch die Größe des zugrunde liegenden numerischen Typs begrenzt. Der größte verfügbare numerische Typ, den Sie verwenden können, ist UInt64 , mit dem Sie 64 verschiedene (nicht kombinierte) Flag- UInt64 angeben können. Das enum Schlüsselwort verwendet standardmäßig den zugrunde liegenden Typ int ( Int32 . Der Compiler erlaubt die Deklaration von Werten, die breiter als 32 Bit sind. Diese werden ohne Vorwarnung umgebrochen und führen zu zwei oder mehr Enumerationsmitgliedern mit demselben Wert. Wenn eine Aufzählung ein Bitset mit mehr als 32 Flags enthalten soll, müssen Sie daher explizit einen größeren Typ angeben:

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

Obwohl Flags oft nur ein einzelnes Bit sind, können sie zur einfacheren Verwendung in benannten "Sets" kombiniert werden.

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

Um zu vermeiden, dass die Dezimalwerte von Zweierpotenzen ausgegeben werden, kann der Operator für die linke Umschalttaste (<<) auch verwendet werden, um dieselbe Aufzählung zu deklarieren

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

Ab C # 7.0 können auch binäre Literale verwendet werden.

Um zu überprüfen, ob für den Wert der Aufzählungsvariablen ein bestimmtes Flag gesetzt ist, kann die HasFlag Methode verwendet werden. Sagen wir, wir haben

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

Und einen value

var value = MyEnum.One | MyEnum.Two;

Mit HasFlag wir überprüfen, ob eines der Flags gesetzt ist

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

Außerdem können wir alle Werte von enum durchlaufen, um alle gesetzten Flags zu erhalten

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

Oder

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

Alle drei Beispiele werden gedruckt:

Enum has One
Enum has Two

Testen Sie Aufzählungswerte im Flags-Stil mit bitweiser Logik

Ein Aufzählungswert im Flags-Stil muss mit bitweiser Logik getestet werden, da er möglicherweise keinem einzelnen Wert entspricht.

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

    Default = Option1 | Option3,
}

Der Default ist eigentlich eine Kombination aus zwei anderen, die mit einem bitweisen ODER verknüpft sind. Um das Vorhandensein einer Flagge zu testen, müssen wir ein bitweises UND verwenden.

var value = FlagsEnum.Default;

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

Assert.True(isOption2And3Set);

Aufzählung zu String und zurück

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

Standardwert für Aufzählung == NULL

Der Standardwert für eine Aufzählung ist Null . Wenn eine Aufzählung keinen Artikel mit dem Wert Null definiert, ist der Standardwert Null.

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

Beispiel: https://dotnetfiddle.net/l5Rwie

Enum-Grundlagen

Von MSDN :

Ein Aufzählungstyp (auch als Aufzählung oder Aufzählung bezeichnet) bietet eine effiziente Methode zum Definieren einer Menge von benannten Integralkonstanten , die einer Variablen zugewiesen werden können .

Im Wesentlichen ist eine Aufzählung ein Typ, der nur einen Satz endlicher Optionen zulässt, und jede Option entspricht einer Zahl. Standardmäßig steigen diese Zahlen in der Reihenfolge, in der die Werte deklariert werden, beginnend mit Null. Zum Beispiel könnte man eine Aufzählung für die Wochentage festlegen:

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

Dieses Enum könnte folgendermaßen verwendet werden:

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

Standardmäßig ist der zugrunde liegende Typ jedes Elements in der enum int , aber auch byte , sbyte , short , ushort , uint , long und ulong können verwendet werden. Wenn Sie einen anderen Typ als int , müssen Sie den Typ mit einem Doppelpunkt nach dem Aufzählungsnamen angeben:

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

Die Zahlen hinter dem Namen sind jetzt Bytes anstelle von ganzen Zahlen. Sie können den zugrunde liegenden Typ der Aufzählung folgendermaßen erhalten:

Enum.GetUnderlyingType(typeof(Days)));

Ausgabe:

System.Byte

Demo: .NET Geige

Bitweise Manipulation über Enummen

Das FlagsAttribute sollte immer dann verwendet werden, wenn das Aufzählungszeichen eine Sammlung von Flags und nicht einen einzelnen Wert darstellt. Der numerische Wert, der jedem Aufzählungswert zugewiesen wird, erleichtert die Bearbeitung von Aufzählungen mit bitweisen Operatoren.

Beispiel 1: Mit [Flags]

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

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

druckt Rot, Blau

Beispiel 2: Ohne [Flags]

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

druckt 3

Die << -Notation für Flags verwenden

Der Linksverschiebungsoperator ( << ) kann in Flag-Enumendeklarationen verwendet werden, um sicherzustellen, dass jedes Flag in binärer Darstellung genau eine 1 , wie es Flags sollten.

Dies hilft auch, die Lesbarkeit großer Aufzählungen mit vielen Flags zu verbessern.

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

Es ist offensichtlich, dass MyEnum nur richtige Flaggen enthält und keine unordentlichen Flag30 = 1073741822 wie Flag30 = 1073741822 (oder 111111111111111111111111111110 in binär), was ungeeignet ist.

Hinzufügen zusätzlicher Beschreibungsinformationen zu einem Aufzählungswert

In einigen Fällen möchten Sie möglicherweise eine zusätzliche Beschreibung zu einem Aufzählungswert hinzufügen, beispielsweise wenn der Aufzählungswert selbst weniger lesbar ist als der, den Sie dem Benutzer anzeigen möchten. In solchen Fällen können Sie die System.ComponentModel.DescriptionAttribute Klasse verwenden.

Zum Beispiel:

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

Wenn Sie nun die Beschreibung eines bestimmten Aufzählungswerts zurückgeben möchten, können Sie Folgendes tun:

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

Dies kann auch leicht in eine Erweiterungsmethode für alle Enums umgewandelt werden:

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

Und dann einfach wie Console.WriteLine(result.GetDescription()); verwendet: Console.WriteLine(result.GetDescription());

Hinzufügen und Entfernen von Werten zur markierten Aufzählung

Dieser Code dient zum Hinzufügen und Entfernen eines Wertes aus einer gekennzeichneten Enum-Instanz:

[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    

Aufzählungen können unerwartete Werte enthalten

Da eine Enumeration in und von ihrem zugrunde liegenden Integraltyp umgewandelt werden kann, kann der Wert außerhalb des Wertebereichs liegen, der in der Definition des Enummentyps angegeben ist.

Obwohl unter dem Aufzählungstyp DaysOfWeek nur 7 definierte Werte vorhanden sind, kann er trotzdem einen beliebigen int Wert enthalten.

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

Derzeit gibt es keine Möglichkeit, eine Aufzählung zu definieren, die dieses Verhalten nicht aufweist.

Enum.IsDefined Aufzählungswerte können jedoch mithilfe der Methode Enum.IsDefined . Zum Beispiel,

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


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow