Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln innehåller ytterligare kommentarer till referensdokumentationen för det här API:et.
En uppräkning är en uppsättning namngivna konstanter vars underliggande typ är någon integrerad typ. Om ingen underliggande typ uttryckligen deklareras används Int32.
Enum är basklassen för alla uppräkningar i .NET. Uppräkningstyper definieras av nyckelordet enum
i C#, Enum
...End Enum
i Visual Basic och nyckelordet type
i F#.
Enum innehåller metoder för att jämföra instanser av den här klassen, konvertera värdet för en instans till dess strängrepresentation, konvertera strängrepresentationen av ett tal till en instans av den här klassen och skapa en instans av en angiven uppräkning och ett angivet värde.
Du kan också behandla en uppräkning som ett bitfält. Mer information finns i avsnittet Icke-exklusiva medlemmar, avsnittet om attributet Flaggor, och FlagsAttribute.
Skapa en uppräkningstyp
Programmeringsspråk tillhandahåller vanligtvis syntax för att deklarera en uppräkning som består av en uppsättning namngivna konstanter och deras värden. I följande exempel visas syntaxen som används av C#, F# och Visual Basic för att definiera en uppräkning. Den skapar en uppräkning med namnet ArrivalStatus
som har tre medlemmar: ArrivalStatus.Early
, ArrivalStatus.OnTime
och ArrivalStatus.Late
. Observera att uppräkningen i alla fall inte uttryckligen ärver från Enum; arvsrelationen hanteras implicit av kompilatorn.
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
Varning
Du bör aldrig skapa en uppräkningstyp vars underliggande typ inte är integrerad eller Char. Även om du kan skapa en sådan uppräkningstyp med hjälp av reflektion, är metodanrop som använder den resulterande typen otillförlitliga och kan också utlösa ytterligare undantag.
Instansiera en uppräkningstyp
Du kan instansiera en uppräkningstyp precis som du instansierar andra värdetyper: genom att deklarera en variabel och tilldela en av uppräkningskonstanterna till den. I följande exempel instansieras en ArrivalStatus
vars värde är ArrivalStatus.OnTime
.
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)
Du kan också instansiera ett uppräkningsvärde på följande sätt:
Genom att använda ett visst programmeringsspråks funktioner för att omvandla (som i C#) eller konvertera (som i Visual Basic) ett heltalsvärde till ett uppräkningsvärde. I följande exempel skapas ett
ArrivalStatus
objekt vars värdeArrivalStatus.Early
på det här sättet.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)
Genom att anropa dess implicita parameterlösa konstruktor. Som följande exempel visar är det underliggande värdet för uppräkningsinstansen i det här fallet 0. Detta är dock inte nödvändigtvis värdet för en giltig konstant i uppräkningen.
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)
Genom att anropa metoden Parse eller TryParse för att parsa en sträng som innehåller namnet på en konstant i uppräkningen. Mer information finns i avsnittet Parsning av räknebara värden.
Genom att anropa metoden ToObject för att konvertera ett integralvärde till en uppräkningstyp. Mer information finns i avsnittet Utföra konverteringar.
Bästa praxis för uppräkning
Vi rekommenderar att du använder följande metodtips när du definierar uppräkningstyper:
Om du inte har definierat en uppräkningsmedlem vars värde är 0 bör du överväga att skapa en
None
uppräknad konstant. Som standard initieras det minne som används för uppräkningen till noll av den gemensamma språkkörningen. Om du inte definierar en konstant vars värde är noll kommer uppräkningen därför att innehålla ett ogiltigt värde när det skapas.Om det finns ett uppenbart standardfall som programmet måste representera kan du överväga att använda en uppräknad konstant vars värde är noll för att representera det. Om det inte finns något standardfall bör du överväga att använda en uppräknad konstant vars värde är noll för att ange det fall som inte representeras av någon av de andra uppräknade konstanterna.
Ange inte uppräknade konstanter som är reserverade för framtida användning.
När du definierar en metod eller egenskap som tar en uppräknad konstant som ett värde bör du överväga att validera värdet. Anledningen är att du kan omvandla ett numeriskt värde till uppräkningstypen även om det numeriska värdet inte har definierats i uppräkningen.
Ytterligare metodtips för uppräkningstyper vars konstanter är bitfält visas i avsnittet Icke-exklusiva medlemmar och attributet Flaggor.
Utföra åtgärder med uppräkningar
Du kan inte definiera nya metoder när du skapar en uppräkning. En uppräkningstyp ärver dock en fullständig uppsättning statiska metoder och instansmetoder från klassen Enum. Följande avsnitt undersöker de flesta av dessa metoder, förutom flera andra metoder som ofta används när du arbetar med uppräkningsvärden.
Utföra konverteringar
Du kan konvertera mellan en uppräkningsmedlem och dess underliggande typ med hjälp av en gjutning (i C# och F#) eller konverteringsoperator (i Visual Basic). I F# används även funktionen enum
. I följande exempel används gjutnings- eller konverteringsoperatorer för att utföra konverteringar både från ett heltal till ett uppräkningsvärde och från ett uppräkningsvärde till ett heltal.
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)
Klassen Enum innehåller också en ToObject-metod som konverterar ett värde av valfri integraltyp till ett uppräkningsvärde. I följande exempel används metoden ToObject(Type, Int32) för att konvertera en Int32 till ett ArrivalStatus
värde. Observera att eftersom ToObject returnerar ett värde av typen Objectkan det fortfarande vara nödvändigt att använda en gjutnings- eller konverteringsoperator för att omvandla objektet till uppräkningstypen.
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)
När du konverterar ett heltal till ett uppräkningsvärde är det möjligt att tilldela ett värde som faktiskt inte är medlem i uppräkningen. För att förhindra detta kan du skicka heltalet till metoden IsDefined innan du utför konverteringen. I följande exempel används den här metoden för att avgöra om elementen i en matris med heltalsvärden kan konverteras till ArrivalStatus
värden.
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
Även om klassen Enum innehåller explicita gränssnittsimplementeringar av IConvertible-gränssnittet för konvertering från ett uppräkningsvärde till en integrerad typ, bör du använda metoderna för klassen Convert, till exempel ToInt32, för att utföra dessa konverteringar. I följande exempel visas hur du kan använda metoden GetUnderlyingType tillsammans med metoden Convert.ChangeType för att konvertera ett uppräkningsvärde till dess underliggande typ. Observera att det här exemplet inte kräver att den underliggande typen av uppräkning är känd vid kompileringstillfället.
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
Analysera uppräkningsvärden
Med metoderna Parse och TryParse kan du konvertera strängrepresentationen av ett uppräkningsvärde till det värdet. Strängrepresentationen kan vara antingen namnet eller det underliggande värdet för en uppräkningskonstant. Observera att parsningsmetoderna konverterar strängrepresentationer av tal som inte är medlemmar i en viss uppräkning om strängarna kan konverteras till ett värde av uppräkningens underliggande typ. För att förhindra detta kan IsDefined-metoden anropas för att säkerställa att resultatet av parsningsmetoden är ett giltigt uppräkningsvärde. Exemplet illustrerar den här metoden och visar anrop till både metoderna Parse(Type, String) och Enum.TryParse<TEnum>(String, TEnum). Observera att den icke-generiska parsningsmetoden returnerar ett objekt som du kan behöva konvertera (i C# och F#) eller konvertera (i Visual Basic) till lämplig uppräkningstyp.
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
Formatera uppräkningsvärden
Du kan konvertera uppräkningsvärden till deras strängrepresentationer genom att anropa den statiska metoden Format, liksom överlagringarna av instansmetoden ToString. Du kan använda en formatsträng för att styra exakt hur ett uppräkningsvärde representeras som en sträng. Mer information finns i Uppräkningsformatsträngar. I följande exempel används var och en av de uppräkningsformatsträngar som stöds ("G" eller "g", "D" eller "d", "X" eller "x" och "F" eller "f" ) för att konvertera en medlem i ArrivalStatus
uppräkning till dess strängrepresentationer.
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
Iterera uppräkningsmedlemmar
Den Enum typen implementerar inte gränssnittet IEnumerable eller IEnumerable<T>, vilket skulle göra det möjligt för dig att iterera över medlemmar i en samling med hjälp av en foreach
(i C#), for..in
(i F#) eller For Each
(i Visual Basic). Du kan dock räkna upp medlemmar på något av två sätt.
Du kan anropa metoden GetNames för att hämta en strängmatris som innehåller namnen på uppräkningsmedlemmarna. För varje element i strängmatrisen kan du anropa metoden Parse för att konvertera strängen till motsvarande uppräkningsvärde. I följande exempel visas den här metoden.
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)
Du kan anropa metoden GetValues för att hämta en matris som innehåller de underliggande värdena i uppräkningen. För varje element i matrisen kan du anropa metoden ToObject för att konvertera heltalet till motsvarande uppräkningsvärde. I följande exempel visas den här metoden.
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)
Icke-exklusiva medlemmar och attributet Flaggor
En vanlig användning av en uppräkning är att representera en uppsättning ömsesidigt uteslutande värden. En ArrivalStatus
-instans kan till exempel ha värdet Early
, OnTime
eller Late
. Det är meningslöst att värdet för en ArrivalStatus
instans återspeglar mer än en uppräkningskonstant.
I andra fall kan dock värdet för ett uppräkningsobjekt innehålla flera uppräkningsmedlemmar och varje medlem representerar ett bitfält i uppräkningsvärdet. Attributet FlagsAttribute kan användas för att indikera att uppräkningen består av bitfält. En uppräkning med namnet Pets
kan till exempel användas för att ange vilka typer av husdjur som finns i ett hushåll. Det kan definieras på följande sätt.
[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
Den Pets
uppräkningen kan sedan användas enligt följande exempel.
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)
Följande metodtips bör användas när du definierar en bitvis uppräkning och tillämpar attributet FlagsAttribute.
Använd det FlagsAttribute anpassade attributet för en uppräkning endast om en bitvis åtgärd (AND, OR, EXCLUSIVE OR) ska utföras på ett numeriskt värde.
Definiera uppräkningskonstanter i två krafter, dvs. 1, 2, 4, 8 och så vidare. Det innebär att de enskilda flaggorna i kombinerade uppräkningskonstanter inte överlappar varandra.
Överväg att skapa en uppräknad konstant för vanliga flaggkombinationer. Om du till exempel har en uppräkning som används för fil-I/O-åtgärder som innehåller de uppräknade konstanterna
Read = 1
ochWrite = 2
kan du skapa den uppräknade konstantenReadWrite = Read OR Write
, som kombinerar flaggornaRead
ochWrite
. Dessutom kan den bitvis OR-åtgärd som används för att kombinera flaggorna betraktas som ett avancerat begrepp under vissa omständigheter som inte bör krävas för enkla uppgifter.Var försiktig om du definierar ett negativt tal som en flagga uppräknad konstant eftersom många flaggpositioner kan vara inställda på 1, vilket kan göra koden förvirrande och uppmuntra kodfel.
Ett praktiskt sätt att testa om en flagga anges i ett numeriskt värde är att anropa instansen HasFlag-metoden, som du ser i följande exempel.
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.
Det motsvarar att utföra en bitvis AND-åtgärd mellan det numeriska värdet och den flagga uppräknade konstanten, som anger alla bitar i det numeriska värdet till noll som inte motsvarar flaggan och sedan testar om resultatet av åtgärden är lika med den uppräknade flaggans konstant. Detta illustreras i följande exempel.
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.
Använd
None
som namnet på den uppräknade flaggans konstant vars värde är noll. Du kan inte använda denNone
uppräknade konstanten i en bitvis AND-åtgärd för att testa för en flagga eftersom resultatet alltid är noll. Du kan dock utföra en logisk jämförelse, inte en bitvis, mellan det numeriska värdet och denNone
uppräknade konstanten för att avgöra om några bitar i det numeriska värdet har angetts. Detta illustreras i följande exempel.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.
Definiera inte ett uppräkningsvärde enbart för att spegla uppräkningstillståndet. Definiera till exempel inte en uppräknad konstant som bara markerar slutet på uppräkningen. Om du behöver fastställa det sista värdet för uppräkningen kontrollerar du uttryckligen det värdet. Dessutom kan du utföra en intervallkontroll för den första och sista uppräknade konstanten om alla värden inom intervallet är giltiga.
Lägga till uppräkningsmetoder
Eftersom uppräkningstyper definieras av språkstrukturer, till exempel enum
(C#) och Enum
(Visual Basic), kan du inte definiera anpassade metoder för en annan uppräkningstyp än de metoder som ärvs från klassen Enum. Du kan dock använda tilläggsmetoder för att lägga till funktioner i en viss uppräkningstyp.
I följande exempel representerar uppräkningen Grades
de bokstavsbetyg som en elev kan få i en kurs. En tilläggsmetod med namnet Passing
läggs till i den Grades
typen så att varje instans av den typen nu "vet" om den representerar ett godkänt betyg eller inte. Klassen Extensions
innehåller också en statisk läs- och skrivvariabel som definierar det lägsta godkänt betyget. Returvärdet för Passing
-tilläggsmetoden återspeglar variabelns aktuella värde.
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.
Exempel
I följande exempel visas hur du använder en uppräkning för att representera namngivna värden och en annan uppräkning som representerar namngivna bitfält.
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