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
ledenRed
,Green
enBlue
.eindvoorbeeld
19.2 Opsommingsdeclaraties
Een enum-declaratie declareert een nieuw enumtype. Een opsommingsdeclaratie begint met het trefwoord enum
en 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 eenintegral_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
long
gebruiken, zoals in het voorbeeld, om het gebruik van waarden in het bereik van maar niet in het bereik vanint
long
, 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). abstract
De , en , en sealed
static
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
-1
en-2
-3
zich niet in het bereik van het onderliggende integrale typeuint
bevinden.eindvoorbeeld
Meerdere enum-leden kunnen dezelfde gekoppelde waarde delen.
Voorbeeld: Het voorbeeld
enum Color { Red, Green, Blue, Max = Blue }
toont een enum waarin twee enumleden
Blue
Max
dezelfde 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 waarde10
krijgt ;- 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
enB
cirkelvormig zijn.A
is expliciet afhankelijkB
van enB
is impliciet afhankelijkA
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:
==
, ,!=
<
,>
, , ,<=
>=
(§12.12.6)- binair
+
(§12.10.5) - binair
-
(§12.10.6) ^
, ,|
(&
§12.13.3)~
(§12.9.5)++
,--
(§12.8.15 en §12.9.6)sizeof
(§23.6.9)
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.
ECMA C# draft specification