Sök…


Introduktion

Ett enum kan härledas från någon av följande typer: byte, sbyte, kort, ushort, int, uint, long, ulong. Standardvärdet är int och kan ändras genom att ange typen i enum-definitionen:

public enum Veckodag: byte {måndag = 1, tisdag = 2, onsdag = 3, torsdag = 4, fredag = 5}

Detta är användbart när P / anropar till inbyggd kod, mappning till datakällor och liknande omständigheter. I allmänhet bör standardintyget användas, eftersom de flesta utvecklare förväntar sig att enum ska vara ett int.

Syntax

  • enum Färger {Röd, Grön, Blå} // Enumdeklaration
  • enum Färger: byte {Röd, Grön, Blå} // Deklaration med specifik typ
  • enum Färger {Röd = 23, Grön = 45, Blå = 12} // Deklaration med definierade värden
  • Colors.Red // Få åtkomst till ett element i en Enum
  • int-värde = (int) Färger.Röd // Få int-värdet för ett enum-element
  • Färger färg = (Färger) intValue // Få ett enum-element från int

Anmärkningar

En Enum (förkortning för "uppräknat typ") är en typ som består av en uppsättning av namngivna konstanter, representerade av en typspecifik identifierare.

Enums är mest användbara för att representera koncept som har ett (vanligtvis litet) antal möjliga diskreta värden. Till exempel kan de användas för att representera en veckodag eller en månad på året. De kan också användas som flaggor som kan kombineras eller kontrolleras med bitvisa operationer.

Få alla medlemmarnas värden på enum

enum MyEnum
{
    One,
    Two,
    Three
}

foreach(MyEnum e in Enum.GetValues(typeof(MyEnum)))
    Console.WriteLine(e);

Detta kommer att skriva ut:

One
Two
Three

Enum som flaggor

FlagsAttribute kan tillämpas på ett enum som ändrar beteendet hos ToString() att matcha karaktären på enum:

[Flags]
enum MyEnum
{
    //None = 0, can be used but not combined in bitwise operations
    FlagA = 1,
    FlagB = 2,
    FlagC = 4,
    FlagD = 8  
    //you must use powers of two or combinations of powers of two 
    //for bitwise operations to work
}

var twoFlags = MyEnum.FlagA | MyEnum.FlagB;

// This will enumerate all the flags in the variable: "FlagA, FlagB".
Console.WriteLine(twoFlags);

Eftersom FlagsAttribute förlitar sig på att uppräkningskonstanterna är krafter för två (eller deras kombinationer) och enumvärden i slutändan är numeriska värden, begränsas du av storleken på den underliggande numeriska typen. Den största tillgängliga numeriska typen som du kan använda är UInt64 , som gör att du kan ange 64 distinkta (icke-kombinerade) flagga enumkonstanter. enum nyckelordet är standardvärde för den underliggande typen int , som är Int32 . Kompilatorn tillåter deklarationen av värden bredare än 32 bitar. De kommer att bryta runt utan varning och resultera i två eller flera medlemmar av samma värde. Därför, om ett enum är tänkt att rymma en bitsats med mer än 32 flaggor, måste du ange en större typ uttryckligen:

public enum BigEnum : ulong
{
    BigValue = 1 << 63
}

Även om flaggor ofta bara är en enda bit, kan de kombineras till namngivna "uppsättningar" för enklare användning.

[Flags]
enum FlagsEnum
{
    None = 0,
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
       
    Default = Option1 | Option3,
    All = Option1 | Option2 | Option3,
}

För att undvika att stämma upp decimalvärdena för krafter för två, kan vänsterförskjutningsoperatören (<<) också användas för att förklara samma enum

[Flags]
enum FlagsEnum
{
    None = 0,
    Option1 = 1 << 0,
    Option2 = 1 << 1,
    Option3 = 1 << 2,
       
    Default = Option1 | Option3,
    All = Option1 | Option2 | Option3,
}

Från och med C # 7.0 kan binära bokstäver också användas.

För att kontrollera om värdet på enumvariabeln har en viss HasFlag kan HasFlag metoden användas. Låt oss säga att vi har det

[Flags]
enum MyEnum
{
    One = 1,
    Two = 2,
    Three = 4
}

Och ett value

var value = MyEnum.One | MyEnum.Two;

Med HasFlag vi kontrollera om någon av flaggorna är inställd

if(value.HasFlag(MyEnum.One))
    Console.WriteLine("Enum has One");

if(value.HasFlag(MyEnum.Two))
    Console.WriteLine("Enum has Two");

if(value.HasFlag(MyEnum.Three))
    Console.WriteLine("Enum has Three");

Vi kan också upprepa alla värden på enum för att få alla inställda flaggor

var type = typeof(MyEnum);
var names = Enum.GetNames(type);

foreach (var name in names)
{
    var item = (MyEnum)Enum.Parse(type, name);

    if (value.HasFlag(item))
        Console.WriteLine("Enum has " + name);
}

Eller

foreach(MyEnum flagToCheck in Enum.GetValues(typeof(MyEnum)))
{
    if(value.HasFlag(flagToCheck))
    {
         Console.WriteLine("Enum has " + flagToCheck);
    }
}

Alla tre exemplen kommer att skriva ut:

Enum has One
Enum has Two

Testa enumvärden med flaggstil med bitvis logik

Ett enumvärde i flaggstil måste testas med bitvis logik eftersom det kanske inte matchar ett enda värde.

[Flags]
enum FlagsEnum
{
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Option2And3 = Option2 | Option3;

    Default = Option1 | Option3,
}

Default är faktiskt en kombination av två andra som slås samman med lite eller ELLER. Därför för att testa på förekomsten av en flagga måste vi använda lite och OCH.

var value = FlagsEnum.Default;

bool isOption2And3Set = (value & FlagsEnum.Option2And3) == FlagsEnum.Option2And3;

Assert.True(isOption2And3Set);

Enum to string och back

public enum DayOfWeek
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

    
// Enum to string
string thursday = DayOfWeek.Thursday.ToString(); // "Thursday"

string seventhDay = Enum.GetName(typeof(DayOfWeek), 6); // "Saturday"

string monday = Enum.GetName(typeof(DayOfWeek), DayOfWeek.Monday); // "Monday"


// String to enum (.NET 4.0+ only - see below for alternative syntax for earlier .NET versions)
DayOfWeek tuesday;
Enum.TryParse("Tuesday", out tuesday); // DayOfWeek.Tuesday

DayOfWeek sunday;
bool matchFound1 = Enum.TryParse("SUNDAY", out sunday); // Returns false (case-sensitive match)

DayOfWeek wednesday;
bool matchFound2 = Enum.TryParse("WEDNESDAY", true, out wednesday); // Returns true; DayOfWeek.Wednesday (case-insensitive match)


// String to enum (all .NET versions)
DayOfWeek friday = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "Friday"); // DayOfWeek.Friday

DayOfWeek caturday = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "Caturady"); // Thows ArgumentException

// All names of an enum type as strings
string[] weekdays = Enum.GetNames(typeof(DayOfWeek));

Standardvärde för enum == NUL

Standardvärdet för enum är noll . Om en enum inte definierar ett objekt med ett värde på noll kommer standardvärdet att vara noll.

public class Program
{        
    enum EnumExample
    {
        one = 1,
        two = 2
    }
    
    public void Main()
    {              
        var e = default(EnumExample);
        
        if (e == EnumExample.one)
            Console.WriteLine("defaults to one");
        else
            Console.WriteLine("Unknown");    
    }    
}

Exempel: https://dotnetfiddle.net/l5Rwie

Enums grunder

Från MSDN :

En uppräkningstyp (även benämnd en uppräkning eller enum) ger ett effektivt sätt att definiera en uppsättning namngivna integralkonstanter som kan tilldelas en variabel .

I huvudsak är enum en typ som endast tillåter en uppsättning begränsade alternativ, och varje alternativ motsvarar ett nummer. Som standard ökar dessa nummer i den ordning värdena deklareras, med början från noll. Till exempel kan man förklara enum för veckodagarna:

public enum Day
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

Det enumet kan användas så här:

// Define variables with values corresponding to specific days
Day myFavoriteDay = Day.Friday;
Day myLeastFavoriteDay = Day.Monday;

// Get the int that corresponds to myFavoriteDay
// Friday is number 4
int myFavoriteDayIndex = (int)myFavoriteDay;

// Get the day that represents number 5
Day dayFive = (Day)5;

Som standard är den underliggande typen av varje element i enum int , men byte , sbyte , short , ushort , uint , long och ulong kan också användas. Om du använder en annan typ än int , måste du ange typen med hjälp av en kolon efter enum-namnet:

public enum Day : byte 
{
    // same as before 
}

Siffrorna efter namnet är nu byte istället för heltal. Du kan få den underliggande typen av enum enligt följande:

Enum.GetUnderlyingType(typeof(Days)));

Produktion:

System.Byte

Demo: .NET-fiol

Bitvis manipulation med enums

FlagsAttribute ska användas närhelst den summan representerar en samling flaggor, snarare än ett enda värde. Det numeriska värdet som tilldelas varje enumvärde hjälper till när man manipulerar enums med bitvisa operatörer.

Exempel 1: Med [flaggor]

[Flags]
enum Colors
{
    Red=1,
    Blue=2,
    Green=4,
    Yellow=8
}

var color = Colors.Red | Colors.Blue;
Console.WriteLine(color.ToString());

skriver ut röd, blå

Exempel 2: Utan [flaggor]

enum Colors
{
    Red=1,
    Blue=2,
    Green=4,
    Yellow=8
}
var color = Colors.Red | Colors.Blue;
Console.WriteLine(color.ToString());

utskrifter 3

Använda << notation för flaggor

Vänsterförskjutningsoperatören ( << ) kan användas i flagginum-deklarationer för att säkerställa att varje flagga har exakt en 1 i binär representation, som flaggor borde.

Detta hjälper också till att förbättra läsbarheten för stora enums med många flaggor i dem.

[Flags]
public enum MyEnum 
{
    None  = 0,
    Flag1 = 1 << 0,
    Flag2 = 1 << 1,
    Flag3 = 1 << 2,
    Flag4 = 1 << 3,
    Flag5 = 1 << 4,
    ...
    Flag31 = 1 << 30
}

Det är uppenbart nu att MyEnum innehåller ordentliga flaggor och inte några röriga saker som Flag30 = 1073741822 (eller 111111111111111111111111111110 i binär) vilket är olämpligt.

Lägga till ytterligare beskrivningsinformation till ett enumvärde

I vissa fall kanske du vill lägga till en ytterligare beskrivning till ett enumvärde, till exempel när själva enumvärdet är mindre läsbart än vad du kanske vill visa användaren. I sådana fall kan du använda klassen System.ComponentModel.DescriptionAttribute .

Till exempel:

public enum PossibleResults
{
    [Description("Success")]
    OK = 1,
    [Description("File not found")]
    FileNotFound = 2,
    [Description("Access denied")]
    AccessDenied = 3
}

Om du vill returnera beskrivningen av ett specifikt enumvärde kan du göra följande:

public static string GetDescriptionAttribute(PossibleResults result)
{
        return ((DescriptionAttribute)Attribute.GetCustomAttribute((result.GetType().GetField(result.ToString())), typeof(DescriptionAttribute))).Description;
}

static void Main(string[] args)
{
    PossibleResults result = PossibleResults.FileNotFound;
    Console.WriteLine(result); // Prints "FileNotFound"
    Console.WriteLine(GetDescriptionAttribute(result)); // Prints "File not found"
}

Detta kan också enkelt omvandlas till en förlängningsmetod för alla enums:

static class EnumExtensions
{
    public static string GetDescription(this Enum enumValue)
    {
        return ((DescriptionAttribute)Attribute.GetCustomAttribute((enumValue.GetType().GetField(enumValue.ToString())), typeof(DescriptionAttribute))).Description;
    }
}

Och sedan lätt att använda så här: Console.WriteLine(result.GetDescription());

Lägg till och ta bort värden från flaggade enum

Den här koden är att lägga till och ta bort ett värde från en flaggad enum-instans:

[Flags]
public enum MyEnum
{
    Flag1 = 1 << 0,
    Flag2 = 1 << 1,
    Flag3 = 1 << 2
}

var value = MyEnum.Flag1;

// set additional value
value |= MyEnum.Flag2;  //value is now Flag1, Flag2
value |= MyEnum.Flag3;  //value is now Flag1, Flag2, Flag3

// remove flag
value &= ~MyEnum.Flag2; //value is now Flag1, Flag3    

Enums kan ha oväntade värden

Eftersom ett enum kan kastas till och från dess underliggande integrerade typ, kan värdet falla utanför det värde som anges i definitionen av enumtypen.

Även om nedanstående enumtyp DaysOfWeek endast har 7 definierade värden kan den fortfarande innehålla valfritt int värde.

public enum DaysOfWeek
{
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thursday = 4,
    Friday = 5,
    Saturday = 6,
    Sunday = 7
}

DaysOfWeek d = (DaysOfWeek)31;
Console.WriteLine(d); // prints 31

DaysOFWeek s = DaysOfWeek.Sunday;
s++; // No error

Det finns för närvarande inget sätt att definiera en enum som inte har detta beteende.

Emellertid kan odefinierade enumvärden detekteras med hjälp av metoden Enum.IsDefined . Till exempel,

DaysOfWeek d = (DaysOfWeek)31;
Console.WriteLine(Enum.IsDefined(typeof(DaysOfWeek),d)); // prints False


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow