Delen via


19 Opsommingen

19.1 Algemeen

Een enum-type is een uniek waardetype (§8.3) dat een set benoemde constanten declareert.

Voorbeeld: Het voorbeeld

enum Color
{
    Red,
    Green,
    Blue
}

declareert een opsommingstype met de naam Color leden Red, Greenen Blue.

eindvoorbeeld

19.2 Opsommingsdeclaraties

Een enum-declaratie declareert een nieuw enumtype. Een opsommingsdeclaratie begint met het trefwoord enumen definieert de naam, toegankelijkheid, het onderliggende type en leden van de enum.

enum_declaration
    : attributes? enum_modifier* 'enum' identifier enum_base? enum_body ';'?
    ;

enum_base
    : ':' integral_type
    | ':' integral_type_name
    ;

integral_type_name
    : type_name // Shall resolve to an integral type other than char
    ;

enum_body
    : '{' enum_member_declarations? '}'
    | '{' enum_member_declarations ',' '}'
    ;

Elk enumtype heeft een bijbehorend integraal type dat het onderliggende type van het enum-type wordt genoemd. Dit onderliggende type moet alle opsommingswaarden kunnen vertegenwoordigen die in de opsomming zijn gedefinieerd. Als de enum_base aanwezig is, wordt het onderliggende type expliciet declareren. Het onderliggende type is een van de integrale typen (§8.3.6) anders dan char. Het onderliggende type kan worden opgegeven door een integral_type (§8.3.5) of een integral_type_name. De integral_type_name oplossing wordt op dezelfde manier opgelost als type_name (§7.8.1), met inbegrip van alle gebruiksrichtlijnen (§14.5) in aanmerking te nemen.

Opmerking: het char type kan niet worden gebruikt als een onderliggend type, hetzij per trefwoord of via een integral_type_name. eindnotitie

Een opsommingsdeclaratie die niet expliciet een onderliggend type declareert, heeft een onderliggend type int.

Voorbeeld: Het voorbeeld

enum Color : long
{
    Red,
    Green,
    Blue
}

declareert een opsomming met een onderliggend type long.

eindvoorbeeld

Opmerking: Een ontwikkelaar kan ervoor kiezen om een onderliggend type te longgebruiken, zoals in het voorbeeld, om het gebruik van waarden in het bereik van maar niet in het bereik vanintlong, of om deze optie voor de toekomst te behouden. eindnotitie

Opmerking: C# staat een volgkomma toe in een enum_body, net zoals in een array_initializer (§17.7). eindnotitie

Een enum-declaratie kan geen typeparameterlijst bevatten, maar een enum genest in een algemene klassedeclaratie of een algemene struct-declaratie is een algemene enumdeclaratie, omdat typeargumenten voor het betreffende type worden opgegeven om een samengesteld type te maken (§8.4).

19.3 Enum modifiers

Een enum_declaration kan eventueel een reeks opsommingsmodifiers bevatten:

enum_modifier
    : 'new'
    | 'public'
    | 'protected'
    | 'internal'
    | 'private'
    ;

Het is een compilatiefout voor dezelfde wijziging die meerdere keren in een opsommingsdeclaratie wordt weergegeven.

De modifiers van een enumdeclaratie hebben dezelfde betekenis als die van een klassedeclaratie (§15.2.2). abstractDe , en , en sealedstatic modifiers zijn echter niet toegestaan in een opsommingsdeclaratie. Opsommingen kunnen niet abstract zijn en staan geen afleiding toe.

19.4 Enum-leden

De hoofdtekst van een declaratie van het enumtype definieert nul of meer enumleden, die de benoemde constanten van het enum-type zijn. Er mogen geen twee enumleden dezelfde naam hebben.

enum_member_declarations
    : enum_member_declaration (',' enum_member_declaration)*
    ;
enum_member_declaration
    : attributes? identifier ('=' constant_expression)?
    ;

Elk enum-lid heeft een gekoppelde constante waarde. Het type van deze waarde is het onderliggende type voor de bevatde enum. De constante waarde voor elk enumlid moet zich in het bereik van het onderliggende type voor de enum bevinden.

Voorbeeld: Het voorbeeld

enum Color: uint
{
    Red = -1,
    Green = -2,
    Blue = -3
}

resulteert in een compilatiefout omdat de constante waarden -1en -2-3 zich niet in het bereik van het onderliggende integrale type uintbevinden.

eindvoorbeeld

Meerdere enum-leden kunnen dezelfde gekoppelde waarde delen.

Voorbeeld: Het voorbeeld

enum Color
{
    Red,
    Green,
    Blue,
    Max = Blue
}

toont een enum waarin twee enumledenBlue Maxdezelfde gekoppelde waarde hebben.

eindvoorbeeld

De bijbehorende waarde van een enum-lid wordt impliciet of expliciet toegewezen. Als de declaratie van het enum-lid een constant_expression initialisatiefunctie heeft, is de waarde van die constante expressie, impliciet geconverteerd naar het onderliggende type enum, de bijbehorende waarde van het enum-lid. Als de declaratie van het enum-lid geen initialisatiefunctie heeft, wordt de bijbehorende waarde impliciet ingesteld, als volgt:

  • Als het enum-lid het eerste enum-lid is dat is gedeclareerd in het enum-type, is de bijbehorende waarde nul.
  • Anders wordt de bijbehorende waarde van het enum-lid verkregen door de bijbehorende waarde van het tekst voorafgaande enumlid met één te verhogen. Deze verhoogde waarde moet zich binnen het bereik van waarden bevinden dat kan worden vertegenwoordigd door het onderliggende type, anders treedt er een compilatietijdfout op.

Voorbeeld: Het voorbeeld

enum Color
{
    Red,
    Green = 10,
    Blue
}

class Test
{
    static void Main()
    {
        Console.WriteLine(StringFromColor(Color.Red));
        Console.WriteLine(StringFromColor(Color.Green));
        Console.WriteLine(StringFromColor(Color.Blue));
    }

    static string StringFromColor(Color c)
    {
        switch (c)
        {
            case Color.Red:
                return $"Red = {(int) c}";
            case Color.Green:
                return $"Green = {(int) c}";
            case Color.Blue:
                return $"Blue = {(int) c}";
            default:
                return "Invalid color";
      }
   }
}

de namen van de enumleden en de bijbehorende waarden worden afgedrukt. De uitvoer is:

Red = 0
Green = 10
Blue = 11

om de volgende redenen:

  • het enum-lid Red wordt automatisch de waarde nul toegewezen (omdat het geen initialisatie heeft en het eerste enum-lid is);
  • het enum-lid Green expliciet de waarde 10krijgt ;
  • en het enum-lid Blue wordt automatisch de waarde toegewezen die groter is dan het lid dat er tekst aan voorafgaat.

eindvoorbeeld

De bijbehorende waarde van een enumlid mag niet direct of indirect de waarde van zijn eigen gekoppelde enumlid gebruiken. Behalve deze circulariteitsbeperking kunnen initialisatiemiddelen van leden vrijelijk verwijzen naar andere initialisatiemiddelen voor opsommingsleden, ongeacht hun tekstpositie. Binnen een initialisatiefunctie voor enumleden worden waarden van andere enum-leden altijd behandeld als het type van hun onderliggende type, zodat casts niet nodig zijn wanneer ze verwijzen naar andere enumleden.

Voorbeeld: Het voorbeeld

enum Circular
{
    A = B,
    B
}

resulteert in een compilatiefout omdat de declaraties van A en B cirkelvormig zijn. A is expliciet afhankelijk B van en B is impliciet afhankelijk A van.

eindvoorbeeld

Enum-leden hebben een naam en bereik op een manier die exact vergelijkbaar is met velden binnen klassen. Het bereik van een enum-lid is de hoofdtekst van het enumtype. Binnen dat bereik kunnen opsommingsleden worden verwezen met hun eenvoudige naam. Uit alle andere code wordt de naam van een enumlid gekwalificeerd met de naam van het enumtype. Enum-leden hebben geen gedeclareerde toegankelijkheid: een enum-lid is toegankelijk als het opsommingstype toegankelijk is.

19.5 Het type System.Enum

Het type System.Enum is de abstracte basisklasse van alle enumtypen (dit verschilt van het onderliggende type enumtype) en de overgenomen leden System.Enum zijn beschikbaar in elk enumtype. Er bestaat een conversie van boksen (§10.2.9) van elk enumtype naar System.Enum, en er bestaat een conversie voor het opheffen van vakken (§10.3.7) van System.Enum elk enumtype.

Houd er rekening mee dat System.Enum het geen enum_type is. In plaats daarvan is het een class_type waarvan alle enum_typezijn afgeleid. Het type wordt overgenomen van het type System.Enum System.ValueType (§8.3.2), dat op zijn beurt overgaat van het type object. Tijdens runtime kan een waarde van het type System.Enum of een verwijzing naar een vakkenwaarde van elk enumtype zijn null .

19.6 Opsommingswaarden en -bewerkingen

Elk enumtype definieert een uniek type; een expliciete opsommingsconversie (§10.3.3) is vereist om te converteren tussen een enumtype en een integraal type, of tussen twee enumtypen. De set waarden van het enum-type is hetzelfde als de set waarden van het onderliggende type en is niet beperkt tot de waarden van de benoemde constanten. Elke waarde van het onderliggende type van een enum kan worden omgezet in het enum-type en is een unieke geldige waarde van dat enum-type.

Enum-leden hebben het type enumtype (behalve binnen andere initialisatieprogramma's voor enumleden: zie §19.4). De waarde van een enum-lid dat is gedeclareerd in enumtype E met de bijbehorende waarde v is (E)v.

De volgende operators kunnen worden gebruikt voor waarden van enumtypen:

Elk enumtype is automatisch afgeleid van de klasse System.Enum (die op zijn beurt afgeleid is van System.ValueType en object). Overgenomen methoden en eigenschappen van deze klasse kunnen dus worden gebruikt voor waarden van een enumtype.