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