System.Enum-Klasse

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Eine Aufzählung ist eine Reihe benannter Konstanten, deren zugrunde liegender Typ ein integraler Typ ist. Wenn kein zugrunde liegender Typ explizit deklariert wird, Int32 wird er verwendet. Enum ist die Basisklasse für alle Enumerationen in .NET. Enumerationstypen werden vom enum Schlüsselwort (keyword) in C#, dem Enum...End Enum -Konstrukt in Visual Basic und dem type Schlüsselwort (keyword) in F# definiert.

Enum stellt Methoden zum Vergleichen von Instanzen dieser Klasse bereit, konvertiert den Wert einer Instanz in seine Zeichenfolgendarstellung, konvertiert die Zeichenfolgendarstellung einer Zahl in eine Instanz dieser Klasse und erstellt eine Instanz einer angegebenen Enumeration und eines angegebenen Werts.

Sie können eine Enumeration auch als Bitfeld behandeln. Weitere Informationen finden Sie im Abschnitt "Nicht exklusive Member" und im Attributabschnitt "Flags" und FlagsAttribute"Flags".

Erstellen eines Enumerationstyps

Programmiersprachen stellen in der Regel Syntax zum Deklarieren einer Aufzählung bereit, die aus einer Gruppe benannter Konstanten und deren Werten besteht. Im folgenden Beispiel wird die Syntax veranschaulicht, die von C#, F# und Visual Basic zum Definieren einer Enumeration verwendet wird. Es erstellt eine Aufzählung mit dem Namen ArrivalStatus drei Member: ArrivalStatus.Early, , ArrivalStatus.OnTimeund ArrivalStatus.Late. Beachten Sie, dass die Enumeration in allen Fällen nicht explizit erbt Enum; die Vererbungsbeziehung wird implizit vom Compiler behandelt.

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

Warnung

Sie sollten niemals einen Enumerationstyp erstellen, dessen zugrunde liegender Typ nicht integral oder Charnicht integral ist. Obwohl Sie einen solchen Enumerationstyp mithilfe von Spiegelung erstellen können, sind Methodenaufrufe, die den resultierenden Typ verwenden, unzuverlässig und können auch zusätzliche Ausnahmen auslösen.

Instanziieren eines Enumerationstyps

Sie können einen Enumerationstyp genauso instanziieren, wie Sie einen anderen Werttyp instanziieren: indem Sie eine Variable deklarieren und ihm eine der Enumerationskonstanten zuweisen. Im folgenden Beispiel wird ein ArrivalStatus Wert instanziiert, dessen Wert lautet 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)

Sie können einen Enumerationswert auch auf folgende Weise instanziieren:

  • Durch Die Verwendung der Features einer bestimmten Programmiersprache zum Umwandeln (wie in C#) oder Konvertieren (wie in Visual Basic) wird ein ganzzahliger Wert in einen Enumerationswert konvertiert. Im folgenden Beispiel wird ein ArrivalStatus Objekt erstellt, dessen Wert auf diese Weise erfolgt ArrivalStatus.Early .

    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)
    
  • Durch Aufrufen des impliziten parameterlosen Konstruktors. Wie im folgenden Beispiel gezeigt, ist in diesem Fall der zugrunde liegende Wert der Enumerationsinstanz 0. Dies ist jedoch nicht unbedingt der Wert einer gültigen Konstante in der Enumeration.

    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)
    
  • Durch Aufrufen der Parse oder TryParse Methode zum Analysieren einer Zeichenfolge, die den Namen einer Konstante in der Enumeration enthält. Weitere Informationen finden Sie im Abschnitt " Parse-Enumerationswerte ".

  • Durch Aufrufen der ToObject Methode zum Konvertieren eines integralen Werts in einen Enumerationstyp. Weitere Informationen finden Sie im Abschnitt "Konvertierungen ausführen".

Bewährte Methoden für Aufzählungen

Es wird empfohlen, beim Definieren von Enumerationstypen die folgenden bewährten Methoden zu verwenden:

  • Wenn Sie kein Enumerationselement definiert haben, dessen Wert 0 ist, sollten Sie eine None aufgezählte Konstante erstellen. Standardmäßig wird der für die Enumeration verwendete Arbeitsspeicher von der Common Language Runtime auf Null initialisiert. Wenn Sie also keine Konstante definieren, deren Wert null ist, enthält die Aufzählung beim Erstellen einen unzulässigen Wert.

  • Wenn es einen offensichtlichen Standardfall gibt, den Ihre Anwendung darstellen muss, sollten Sie eine aufgezählte Konstante verwenden, deren Wert null ist, um sie darzustellen. Wenn kein Standardfall vorhanden ist, sollten Sie eine aufgezählte Konstante verwenden, deren Wert null ist, um den Fall anzugeben, der nicht durch eine der anderen aufgezählten Konstanten dargestellt wird.

  • Geben Sie keine aufgezählten Konstanten an, die für die zukünftige Verwendung reserviert sind.

  • Wenn Sie eine Methode oder Eigenschaft definieren, die eine aufgezählte Konstante als Wert verwendet, sollten Sie die Überprüfung des Werts in Betracht ziehen. Der Grund dafür ist, dass Sie einen numerischen Wert in den Enumerationstyp umwandeln können, auch wenn dieser numerische Wert nicht in der Enumeration definiert ist.

Weitere bewährte Methoden für Enumerationstypen, deren Konstanten Bitfelder sind, werden im Abschnitt "Nicht exklusive Elemente" und im Attributabschnitt "Flags" aufgeführt.

Ausführen von Vorgängen mit Enumerationen

Beim Erstellen einer Enumeration können keine neuen Methoden definiert werden. Ein Enumerationstyp erbt jedoch einen vollständigen Satz statischer und Instanzmethoden aus der Enum Klasse. In den folgenden Abschnitten werden die meisten dieser Methoden zusätzlich zu verschiedenen anderen Methoden, die häufig beim Arbeiten mit Enumerationswerten verwendet werden, erfasst.

Durchführen von Konvertierungen

Sie können zwischen einem Enumerationselement und dem zugrunde liegenden Typ konvertieren, indem Sie einen Umwandlungsoperator (in C# und F#) oder einen Konvertierungsoperator (in Visual Basic) verwenden. In F# wird die enum Funktion ebenfalls verwendet. Im folgenden Beispiel werden Umwandlungs- oder Konvertierungsoperatoren verwendet, um Konvertierungen von einer ganzen Zahl in einen Enumerationswert und von einem Enumerationswert in eine ganze Zahl durchzuführen.

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)

Die Enum Klasse enthält auch eine ToObject Methode, die einen Wert eines beliebigen integralen Typs in einen Enumerationswert konvertiert. Im folgenden Beispiel wird die ToObject(Type, Int32) Methode verwendet, um einen Int32 Wert in einen ArrivalStatus Wert zu konvertieren. Beachten Sie, dass aufgrund des ToObject Rückgabewerts eines Typs Objectdie Verwendung eines Umwandlungs- oder Konvertierungsoperators möglicherweise noch erforderlich ist, um das Objekt in den Enumerationstyp zu umwandeln.

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)

Beim Konvertieren einer ganzen Zahl in einen Enumerationswert ist es möglich, einen Wert zuzuweisen, der nicht tatsächlich ein Element der Enumeration ist. Um dies zu verhindern, können Sie die ganze Zahl an die IsDefined Methode übergeben, bevor Sie die Konvertierung ausführen. Im folgenden Beispiel wird diese Methode verwendet, um zu bestimmen, ob die Elemente in einem Array ganzzahliger Werte in ArrivalStatus Werte konvertiert werden können.

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

Obwohl die Enum Klasse explizite Schnittstellenimplementierungen der IConvertible Schnittstelle zum Konvertieren von einem Enumerationswert in einen integralen Typ bereitstellt, sollten Sie die Methoden der Convert Klasse verwenden, z ToInt32. B. zum Ausführen dieser Konvertierungen. Im folgenden Beispiel wird veranschaulicht, wie Sie die GetUnderlyingType Methode zusammen mit der Convert.ChangeType Methode verwenden können, um einen Enumerationswert in den zugrunde liegenden Typ zu konvertieren. Beachten Sie, dass in diesem Beispiel nicht der zugrunde liegende Typ der Aufzählung zur Kompilierungszeit bekannt sein muss.

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

Analysieren von Enumerationswerten

TryParse Mit Parse den Methoden können Sie die Zeichenfolgendarstellung eines Enumerationswerts in diesen Wert konvertieren. Die Zeichenfolgendarstellung kann entweder der Name oder der zugrunde liegende Wert einer Enumerationskonstante sein. Beachten Sie, dass die Analysemethoden erfolgreich Zeichenfolgendarstellungen von Zahlen konvertieren, die keine Member einer bestimmten Enumeration sind, wenn die Zeichenfolgen in einen Wert des zugrunde liegenden Enumerationstyps konvertiert werden können. Um dies zu verhindern, kann die IsDefined Methode aufgerufen werden, um sicherzustellen, dass das Ergebnis der Analysemethode ein gültiger Enumerationswert ist. Das Beispiel veranschaulicht diesen Ansatz und veranschaulicht Aufrufe sowohl für die Methoden Enum.TryParse<TEnum>(String, TEnum) als auch für die Parse(Type, String) Methoden. Beachten Sie, dass die nicht generische Analysemethode ein Objekt zurückgibt, das Sie möglicherweise in C# und F# umwandeln oder (in Visual Basic) in den entsprechenden Enumerationstyp konvertieren müssen.

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

Formatieren von Enumerationswerten

Sie können Enumerationswerte in ihre Zeichenfolgendarstellungen konvertieren, indem Sie die statische Format Methode sowie die Überladungen der Instanzmethode ToString aufrufen. Sie können eine Formatzeichenfolge verwenden, um die genaue Art und Weise zu steuern, in der ein Enumerationswert als Zeichenfolge dargestellt wird. Weitere Informationen finden Sie unter Enumerationsformatzeichenfolgen. Im folgenden Beispiel wird jede der unterstützten Enumerationsformatzeichenfolgen ("G" oder "g", "D" oder "d", "X" oder "x" und "F" oder "f" ) verwendet, um ein Element der Enumeration in seine ArrivalStatus Zeichenfolgendarstellungen zu konvertieren.

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

Iterate enumeration members

Der Enum Typ implementiert weder die IEnumerableIEnumerable<T> Schnittstelle noch die Schnittstelle, mit der Sie Elemente einer Auflistung mithilfe eines foreach (in C#), for..in (in F#) oder For Each (in Visual Basic) Konstrukts durchlaufen können. Sie können Jedoch Elemente auf zwei Arten aufzählen.

  • Sie können die GetNames Methode aufrufen, um ein Zeichenfolgenarray mit den Namen der Enumerationsmember abzurufen. Als Nächstes können Sie für jedes Element des Zeichenfolgenarrays die Parse Methode aufrufen, um die Zeichenfolge in den entsprechenden Enumerationswert zu konvertieren. Dieser Ansatz wird anhand des folgenden Beispiels veranschaulicht.

    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)
    
  • Sie können die GetValues Methode aufrufen, um ein Array abzurufen, das die zugrunde liegenden Werte in der Enumeration enthält. Als Nächstes können Sie für jedes Element des Arrays die ToObject Methode aufrufen, um die ganze Zahl in den entsprechenden Enumerationswert zu konvertieren. Dieser Ansatz wird anhand des folgenden Beispiels veranschaulicht.

    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)
    

Nicht exklusive Member und das Attribut "Flags"

Eine häufige Verwendung einer Enumeration besteht darin, einen Satz sich gegenseitig ausschließenden Werten darzustellen. Eine Instanz kann z. B ArrivalStatus . einen Wert von Early, , OnTimeoder Late. Es ist nicht sinnvoll, dass der Wert einer ArrivalStatus Instanz mehr als eine Enumerationskonstante widerspiegelt.

In anderen Fällen kann der Wert eines Enumerationsobjekts jedoch mehrere Enumerationsmember enthalten, und jedes Element stellt ein Bitfeld im Enumerationswert dar. Das FlagsAttribute Attribut kann verwendet werden, um anzugeben, dass die Aufzählung aus Bitfeldern besteht. Beispielsweise kann eine Aufzählung namens Pets verwendet werden, um die Arten von Haustieren in einem Haushalt anzugeben. Sie kann wie folgt definiert werden.

[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

Die Pets Aufzählung kann dann wie im folgenden Beispiel dargestellt verwendet werden.

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)

Die folgenden bewährten Methoden sollten beim Definieren einer bitweisen Enumeration und anwenden des FlagsAttribute Attributs verwendet werden.

  • Verwenden Sie das FlagsAttribute benutzerdefinierte Attribut nur für eine Enumeration, wenn ein bitweiser Vorgang (AND, OR, EXCLUSIVE OR) für einen numerischen Wert ausgeführt werden soll.

  • Definieren Sie Enumerationskonstanten in Potenzen von zwei, d. h. 1, 2, 4, 8 usw. Dies bedeutet, dass die einzelnen Flags in kombinierten Enumerationskonstanten nicht überlappen.

  • Erwägen Sie das Erstellen einer aufgezählten Konstante für häufig verwendete Flagkombinationen. Wenn Sie z. B. eine Aufzählung für Datei-E/A-Vorgänge verwenden, die die aufgezählten Konstanten Read = 1 enthalten, und Write = 2erwägen Sie, die aufgezählte Konstante zu erstellen, die die Read enumerierten Konstanten ReadWrite = Read OR Writekombiniert und Write flags kombiniert. Darüber hinaus kann der bitweise ODER-Vorgang, der zum Kombinieren der Flags verwendet wird, unter bestimmten Umständen als ein erweitertes Konzept angesehen werden, das nicht für einfache Aufgaben erforderlich sein sollte.

  • Verwenden Sie Vorsicht, wenn Sie eine negative Zahl als aufgezählte Kennzeichnungskonstante definieren, da viele Flagpositionen möglicherweise auf 1 festgelegt werden, was dazu führen kann, dass Der Code verwirrend ist und Codierungsfehler animiert.

  • Eine praktische Möglichkeit zum Testen, ob ein Flag in einem numerischen Wert festgelegt ist, besteht darin, die Instanzmethode HasFlag aufzurufen, wie im folgenden Beispiel gezeigt.

    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.
    

    Es entspricht dem Ausführen eines bitweisen AND-Vorgangs zwischen dem numerischen Wert und der aufgezählten Flagkonstante, die alle Bits im numerischen Wert auf Null festlegt, die nicht dem Flag entsprechen, und anschließend zu testen, ob das Ergebnis dieses Vorgangs der Aufzählungskonstante entspricht. Dies wird im folgenden Beispiel veranschaulicht.

    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.
    
  • Wird als Name der aufgezählten Flagkonstante verwendet None , deren Wert null ist. Sie können die None aufgezählte Konstante in einem bitweisen AND-Vorgang nicht verwenden, um eine Kennzeichnung zu testen, da das Ergebnis immer null ist. Sie können jedoch einen logischen, nicht bitweisen Vergleich zwischen dem numerischen Wert und der None aufgezählten Konstante durchführen, um zu bestimmen, ob Bits im numerischen Wert festgelegt werden. Dies wird im folgenden Beispiel veranschaulicht.

    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.
    
  • Definieren Sie keinen Enumerationswert nur, um den Zustand der Enumeration selbst zu Spiegel. Definieren Sie beispielsweise keine aufgezählte Konstante, die lediglich das Ende der Enumeration kennzeichnet. Wenn Sie den letzten Wert der Aufzählung ermitteln müssen, überprüfen Sie explizit auf diesen Wert. Darüber hinaus können Sie eine Bereichsprüfung für die erste und letzte aufgezählte Konstante ausführen, wenn alle Werte innerhalb des Bereichs gültig sind.

Hinzufügen von Enumerationsmethoden

Da Enumerationstypen durch Sprachstrukturen wie enum (C#) und Enum (Visual Basic) definiert werden, können Sie keine benutzerdefinierten Methoden für einen anderen Enumerationstyp als die von der Enum Klasse geerbten Methoden definieren. Sie können jedoch Erweiterungsmethoden verwenden, um einem bestimmten Enumerationstyp Funktionen hinzuzufügen.

Im folgenden Beispiel stellt die Grades-Enumeration die möglichen Noten in Buchstaben dar, die ein Schüler im Unterricht erhalten kann. Eine Erweiterungsmethode mit dem Namen Passing wird dem Grades-Typ hinzugefügt, sodass jede Instanz dieses Typs nun „weiß“, ob sie eine Note darstellt, mit der der Schüler bestanden hat. Die Extensions Klasse enthält auch eine statische Lese-/Schreibvariable, die die Mindestnote definiert. Der Rückgabewert der Passing Erweiterungsmethode gibt den aktuellen Wert dieser Variablen wieder.

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.

Beispiele

Das folgende Beispiel veranschaulicht die Verwendung einer Aufzählung zur Darstellung benannter Werte und einer anderen Aufzählung zur Darstellung benannter Bitfelder.

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