Delen via


System.Enum-klasse

In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.

Een opsomming is een set benoemde constanten waarvan het onderliggende type een integraal type is. Als er geen onderliggend type expliciet wordt gedeclareerd, Int32 wordt dit gebruikt. Enum is de basisklasse voor alle opsommingen in .NET. Opsommingstypen worden gedefinieerd door het enum trefwoord in C#, de Enum...End Enum -constructie in Visual Basic en het type trefwoord in F#.

Enum biedt methoden voor het vergelijken van exemplaren van deze klasse, het converteren van de waarde van een exemplaar naar de tekenreeksweergave, het converteren van de tekenreeksweergave van een getal naar een exemplaar van deze klasse en het maken van een exemplaar van een opgegeven opsomming en waarde.

U kunt ook een opsomming behandelen als een bitveld. Zie de sectie Niet-exclusieve leden en de sectie Flags attributen en FlagsAttributevoor meer informatie.

Een opsommingstype maken

Programmeertalen bieden doorgaans syntaxis om een opsomming te declareren die bestaat uit een set benoemde constanten en hun waarden. In het volgende voorbeeld ziet u de syntaxis die wordt gebruikt door C#, F# en Visual Basic om een opsomming te definiëren. Er wordt een opsomming met de naam ArrivalStatus gemaakt, met drie leden: ArrivalStatus.Early, ArrivalStatus.OnTime, en ArrivalStatus.Late. Houd er rekening mee dat de opsomming in alle gevallen niet expliciet wordt overgenomen van Enum; de overnamerelatie wordt impliciet verwerkt door de compiler.

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

Waarschuwing

U moet nooit een opsommingstype maken waarvan het onderliggende type niet-integraal is of Char. Hoewel u een dergelijk opsommingstype kunt maken met behulp van weerspiegeling, zijn methodeaanroepen die het resulterende type gebruiken onbetrouwbaar en kunnen ook extra uitzonderingen genereren.

Een opsommingstype instantiëren

U kunt een opsommingstype instantiëren, net zoals u een ander waardetype maakt: door een variabele te declareren en een van de constanten van de opsomming eraan toe te wijzen. In het volgende voorbeeld wordt een instantie van een ArrivalStatus gemaakt, waarvan de waarde ArrivalStatus.OnTime is.

public class Example
{
   public static void Main()
   {
      ArrivalStatus status = ArrivalStatus.OnTime;
      Console.WriteLine($"Arrival Status: {status} ({status:D})");
   }
}
// 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)

U kunt ook een opsommingswaarde op de volgende manieren instantiëren:

  • Door de functies van een bepaalde programmeertaal te gebruiken om te casten (zoals in C#) of een geheel getal te converteren (zoals in Visual Basic) naar een opsommingswaarde. In het volgende voorbeeld wordt een ArrivalStatus object gemaakt waarvan de waarde op deze manier is ArrivalStatus.Early .

    ArrivalStatus status2 = (ArrivalStatus)1;
    Console.WriteLine($"Arrival Status: {status2} ({status2:D})");
    // 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)
    
  • Door de impliciete parameterloze constructor aan te roepen. Zoals in het volgende voorbeeld wordt weergegeven, is in dit geval de onderliggende waarde van het opsommingsexemplaren 0. Dit is echter niet noodzakelijkerwijs de waarde van een geldige constante in de opsomming.

    ArrivalStatus status1 = new ArrivalStatus();
    Console.WriteLine($"Arrival Status: {status1} ({status1:D})");
    // 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)
    
  • Door de Parse of TryParse methode aan te roepen om een tekenreeks te parseren die de naam van een constante in de opsomming bevat. Zie de sectie Parseerwaarden voor meer informatie.

  • Door de ToObject methode aan te roepen om een integrale waarde te converteren naar een opsommingstype. Zie de sectie Conversies uitvoeren voor meer informatie.

Best practices voor opsomming

U wordt aangeraden de volgende aanbevolen procedures te gebruiken wanneer u opsommingstypen definieert:

  • Als u geen opsommingslid hebt gedefinieerd waarvan de waarde 0 is, kunt u een None opgesomde constante maken. Standaard wordt het geheugen dat wordt gebruikt voor de opsomming geïnitialiseerd tot nul door de algemene taalruntime. Als u dus geen constante definieert waarvan de waarde nul is, bevat de opsomming een ongeldige waarde wanneer deze wordt gemaakt.

  • Als er een duidelijk standaardscenario is dat uw toepassing moet vertegenwoordigen, kunt u overwegen een opgesomde constante te gebruiken waarvan de waarde nul is om deze weer te geven. Als er geen standaardcase is, kunt u overwegen een geïnventariseerd constante te gebruiken waarvan de waarde nul is om de case op te geven die niet wordt vertegenwoordigd door een van de andere opgesomde constanten.

  • Geef geen geïnventareerde constanten op die zijn gereserveerd voor toekomstig gebruik.

  • Wanneer u een methode of eigenschap definieert die een geïnventareerde constante als een waarde gebruikt, kunt u overwegen om de waarde te valideren. De reden hiervoor is dat u een numerieke waarde kunt casten naar het opsommingstype, zelfs als die numerieke waarde niet is gedefinieerd in de opsomming.

Aanvullende aanbevolen procedures voor opsommingstypen waarvan constanten bitvelden zijn, worden vermeld in de sectie Niet-exclusieve leden en de sectie Markeringenkenmerken .

Bewerkingen uitvoeren met opsommingen

U kunt geen nieuwe methoden definiëren wanneer u een opsomming maakt. Een opsommingstype neemt echter een volledige set statische en exemplaarmethoden over van de Enum klasse. In de volgende secties worden de meeste van deze methoden onderzocht, naast verschillende andere methoden die vaak worden gebruikt bij het werken met opsommingswaarden.

Conversies uitvoeren

U kunt converteren tussen een opsommingslid en het onderliggende type met behulp van een cast-operator (in C# en F#) of conversie (in Visual Basic). In F# wordt de enum functie ook gebruikt. In het volgende voorbeeld worden cast- of conversieoperators gebruikt om conversies uit te voeren van zowel een geheel getal naar een opsommingswaarde als van een opsommingswaarde naar een geheel getal.

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)

De Enum klasse bevat ook een ToObject methode waarmee een waarde van elk integraal type wordt geconverteerd naar een opsommingswaarde. In het volgende voorbeeld wordt de ToObject(Type, Int32) methode gebruikt om een Int32 waarde te converteren naar een ArrivalStatus waarde. Omdat de ToObject een waarde van het type Object retourneert, is het mogelijk dat het gebruik van een cast- of conversieoperator nog steeds nodig is om het object naar het opsommingstype te casten.

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)

Wanneer u een geheel getal converteert naar een opsommingswaarde, is het mogelijk om een waarde toe te wijzen die geen lid is van de opsomming. U kunt dit voorkomen door het gehele getal door te geven aan de IsDefined methode voordat u de conversie uitvoert. In het volgende voorbeeld wordt deze methode gebruikt om te bepalen of de elementen in een matrix met gehele getallen kunnen worden geconverteerd naar ArrivalStatus waarden.

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 {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
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

Hoewel de Enum klasse expliciete interface-implementaties van de IConvertible interface biedt voor het converteren van een opsommingswaarde naar een integraal type, moet u de methoden van de Convert klasse gebruiken, zoals ToInt32, om deze conversies uit te voeren. In het volgende voorbeeld ziet u hoe u de GetUnderlyingType methode samen met de Convert.ChangeType methode kunt gebruiken om een opsommingswaarde te converteren naar het onderliggende type. Houd er rekening mee dat in dit voorbeeld niet het onderliggende type van de opsomming bekend moet zijn tijdens het compileren.

ArrivalStatus status = ArrivalStatus.Early;
var number = Convert.ChangeType(status, Enum.GetUnderlyingType(typeof(ArrivalStatus)));
Console.WriteLine($"Converted {status} to {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

Opsommingswaarden parseren

Met de Parse en TryParse methoden kunt u de tekenreeksweergave van een opsommingswaarde converteren naar die waarde. De tekenreeksweergave kan de naam of de onderliggende waarde van een opsommingsconstante zijn. De parseringsmethoden converteren tekenreeksweergaven van getallen die geen lid zijn van een bepaalde opsomming als de tekenreeksen kunnen worden geconverteerd naar een waarde van het onderliggende type van de opsomming. Om dit te voorkomen, kan de IsDefined methode worden aangeroepen om ervoor te zorgen dat het resultaat van de parseringsmethode een geldige opsommingswaarde is. Het voorbeeld illustreert deze benadering en demonstreert aanroepen naar zowel de Parse(Type, String) als de Enum.TryParse<TEnum>(String, TEnum) methoden. Houd er rekening mee dat de niet-algemene parseringsmethode een object retourneert dat u mogelijk moet casten (in C# en F#) of (in Visual Basic) naar het juiste opsommingstype moet converteren.

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 '{number}' to {status1}");
}
catch (FormatException)
{
    Console.WriteLine($"Unable to convert '{number}' to an ArrivalStatus value.");
}

ArrivalStatus status2;
if (Enum.TryParse<ArrivalStatus>(name, out status2))
{
    if (!(Enum.IsDefined(typeof(ArrivalStatus), status2)))
        status2 = ArrivalStatus.Unknown;
    Console.WriteLine($"Converted '{name}' to {status2}");
}
else
{
    Console.WriteLine($"Unable to convert '{number}' to an ArrivalStatus value.");
}
// 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

Opsommingswaarden opmaken

U kunt opsommingswaarden converteren naar hun tekenreeksweergaven door de statische Format methode aan te roepen, evenals de overbelastingen van de instantiemethode ToString . U kunt een notatietekenreeks gebruiken om de precieze manier te bepalen waarop een opsommingswaarde wordt weergegeven als een tekenreeks. Zie Opsommingstekenreeksenvoor meer informatie. In het volgende voorbeeld worden alle ondersteunde opsommingstekenreeksen ('G' of 'g', 'D' of 'd', 'X' of 'x' en 'F' of 'f' gebruikt om een lid van de opsomming te converteren naar de ArrivalStatus tekenreeksweergaven.

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

Opsommingsleden herhalen

Het Enum type implementeert de IEnumerable of IEnumerable<T> interface niet, waarmee u leden van een verzameling kunt herhalen met behulp van een foreach constructie (in C#), for..in (in F#) of For Each (in Visual Basic). U kunt echter op twee manieren leden opsommen.

  • U kunt de GetNames methode aanroepen om een tekenreeksmatrix op te halen die de namen van de opsommingsleden bevat. Vervolgens kunt u voor elk element van de tekenreeksmatrix de Parse methode aanroepen om de tekenreeks te converteren naar de equivalente opsommingswaarde. In het volgende voorbeeld ziet u deze benadering.

    string[] names = Enum.GetNames(typeof(ArrivalStatus));
    Console.WriteLine($"Members of {typeof(ArrivalStatus).Name}:");
    Array.Sort(names);
    foreach (var name in names)
    {
        ArrivalStatus status = (ArrivalStatus)Enum.Parse(typeof(ArrivalStatus), name);
        Console.WriteLine($"   {status} ({status:D})");
    }
    // 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)
    
  • U kunt de GetValues methode aanroepen om een matrix op te halen die de onderliggende waarden in de opsomming bevat. Vervolgens kunt u voor elk element van de matrix de ToObject methode aanroepen om het gehele getal te converteren naar de equivalente opsommingswaarde. In het volgende voorbeeld ziet u deze benadering.

    var values = Enum.GetValues(typeof(ArrivalStatus));
    Console.WriteLine($"Members of {typeof(ArrivalStatus).Name}:");
    foreach (ArrivalStatus status in values)
    {
        Console.WriteLine($"   {status} ({status:D})");
    }
    // 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)
    

Niet-exclusieve leden en het kenmerk Vlaggen

Een veelvoorkomend gebruik van een opsomming is het vertegenwoordigen van een set wederzijds exclusieve waarden. Een ArrivalStatus exemplaar kan bijvoorbeeld een waarde hebben van Early, OnTimeof Late. Het is niet logisch dat de waarde van een ArrivalStatus exemplaar meer dan één opsommingsconstante weergeeft.

In andere gevallen kan de waarde van een opsommingsobject echter meerdere opsommingsleden bevatten en elk lid vertegenwoordigt een bitveld in de opsommingswaarde. Het FlagsAttribute kenmerk kan worden gebruikt om aan te geven dat de opsomming bestaat uit bitvelden. Een opsomming met de naam Pets kan bijvoorbeeld worden gebruikt om de soorten huisdieren in een huishouden aan te geven. Deze kan als volgt worden gedefinieerd.

[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

De Pets opsomming kan vervolgens worden gebruikt zoals wordt weergegeven in het volgende voorbeeld.

Pets familyPets = Pets.Dog | Pets.Cat;
Console.WriteLine($"Pets: {familyPets:G} ({familyPets:D})");
// 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)

De volgende aanbevolen procedures moeten worden gebruikt bij het definiëren van een bitwise opsomming en het toepassen van het FlagsAttribute kenmerk.

  • Gebruik het FlagsAttribute aangepaste kenmerk alleen voor een opsomming als een bitwise bewerking (AND, OR, EXCLUSIVE OR) moet worden uitgevoerd op een numerieke waarde.

  • Opsommingsconstanten definiëren in machten van twee, dat wil gezegd: 1, 2, 4, 8, enzovoort. Dit betekent dat de afzonderlijke vlaggen in gecombineerde opsommingsconstanten elkaar niet overlappen.

  • Overweeg om een geïnventariseerd constante te maken voor veelgebruikte vlagcombinaties. Als u bijvoorbeeld een opsomming hebt die wordt gebruikt voor bestands-I/O-bewerkingen die de geïnventareerde constanten Read = 1 bevatten, Write = 2kunt u overwegen om de geïnventareerde constante ReadWrite = Read OR Writete maken, waarin de Read en Write vlaggen worden gecombineerd. Bovendien kan de bitsgewijze OR-bewerking die wordt gebruikt om de vlaggen te combineren, worden beschouwd als een geavanceerd concept in sommige omstandigheden dat niet vereist mag zijn voor eenvoudige taken.

  • Wees voorzichtig als u een negatief getal definieert als een markeringsconstante, omdat veel vlagposities kunnen worden ingesteld op 1, waardoor uw code verwarrend kan zijn en coderingsfouten kan stimuleren.

  • Een handige manier om te testen of een vlag is ingesteld in een numerieke waarde, is door de instantiemethode HasFlag aan te roepen, zoals wordt weergegeven in het volgende voorbeeld.

    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.
    

    Het is gelijk aan het uitvoeren van een bitsgewijze AND-bewerking tussen de numerieke waarde en de vlagconstante, waarbij alle bits in de numerieke waarde op nul worden gezet die niet overeenkomen met de vlag, en vervolgens wordt getest of het resultaat van die bewerking gelijk is aan de vlagconstante. Dit wordt geïllustreerd in het volgende voorbeeld.

    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.
    
  • Gebruik None deze naam als de naam van de vlag-opsommingsconstante waarvan de waarde nul is. U kunt de None geïnventareerde constante in een bitwise AND-bewerking niet gebruiken om te testen op een vlag, omdat het resultaat altijd nul is. U kunt echter een logische, niet een bitgewijze vergelijking uitvoeren tussen de numerieke waarde en de None opgesomde constante om te bepalen of bits in de numerieke waarde zijn ingesteld. Dit wordt geïllustreerd in het volgende voorbeeld.

    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.
    
  • Definieer niet alleen een opsommingswaarde om de status van de opsomming zelf te spiegelen. Definieer bijvoorbeeld geen opsommingsconstante die alleen het einde van de opsomming markeert. Als u de laatste waarde van de opsomming wilt bepalen, controleert u expliciet op die waarde. Daarnaast kunt u een bereikcontrole uitvoeren op de eerste en laatste opsommingsconstante als alle waarden binnen het bereik geldig zijn.

Opsommingsmethoden toevoegen

Omdat opsommingstypen worden gedefinieerd door taalstructuren, zoals enum (C#) en Enum (Visual Basic), kunt u geen aangepaste methoden definiëren voor een ander opsommingstype dan die methoden die zijn overgenomen van de Enum klasse. U kunt echter extensiemethoden gebruiken om functionaliteit toe te voegen aan een bepaald opsommingstype.

In het volgende voorbeeld geeft de Grades opsomming de mogelijke cijfers aan die een leerling/student in een klas kan ontvangen. Er wordt een extensiemethode met de naam Passing toegevoegd aan het Grades type, zodat elk exemplaar van dat type nu weet of het een voldoende vertegenwoordigt of niet. De Extensions klasse bevat ook een statische variabele voor lezen/schrijven waarmee het minimum aantal geslaagde cijfers wordt gedefinieerd. De retourwaarde van de Passing extensiemethode weerspiegelt de huidige waarde van die variabele.

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($"{g1} {(g1.Passing() ? "is" : "is not")} a passing grade.");
        Console.WriteLine($"{g2} {(g2.Passing() ? "is" : "is not")} a passing grade.");

        Extensions.minPassing = Grades.C;
        Console.WriteLine("\nRaising the bar!\n");
        Console.WriteLine($"{g1} {(g1.Passing() ? "is" : "is not")} a passing grade.");
        Console.WriteLine($"{g2} {(g2.Passing() ? "is" : "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.
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.

Voorbeelden

In het volgende voorbeeld ziet u hoe u een opsomming gebruikt om benoemde waarden en een andere opsomming weer te geven die benoemde bitvelden vertegenwoordigt.

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: {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