1724 Stimmen

Was bedeutet das [Flags] Enum-Attribut in C#?

Von Zeit zu Zeit sehe ich eine Aufzählung wie die folgende:

[Flags]
public enum Options 
{
    None    = 0,
    Option1 = 1,
    Option2 = 2,
    Option3 = 4,
    Option4 = 8
}

Ich verstehe nicht, was genau die [Flags] Attribut tut.

Hat jemand eine gute Erklärung oder ein Beispiel, das er veröffentlichen könnte?

884voto

Orion Edwards Punkte 117361

Sie können auch Folgendes tun

[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3
}

Ich finde das Bit-Shifting einfacher als die Eingabe von 4, 8, 16, 32 und so weiter. Es hat keine Auswirkung auf den Code, weil alles zur Kompilierzeit gemacht wird

140voto

drzaus Punkte 22843

Kombinierte Antworten https://stackoverflow.com/a/8462/1037948 (Deklaration durch Bit-Shifting) und https://stackoverflow.com/a/9117/1037948 (unter Verwendung von Kombinationen in der Deklaration) können Sie frühere Werte per Bit-Shift verschieben, anstatt Zahlen zu verwenden. Ich empfehle das nicht unbedingt, sondern weise nur darauf hin, dass man das kann.

Anstatt:

[Flags]
public enum Options : byte
{
    None    = 0,
    One     = 1 << 0,   // 1
    Two     = 1 << 1,   // 2
    Three   = 1 << 2,   // 4
    Four    = 1 << 3,   // 8

    // combinations
    OneAndTwo = One | Two,
    OneTwoAndThree = One | Two | Three,
}

Sie können erklären

[Flags]
public enum Options : byte
{
    None    = 0,
    One     = 1 << 0,       // 1
    // now that value 1 is available, start shifting from there
    Two     = One << 1,     // 2
    Three   = Two << 1,     // 4
    Four    = Three << 1,   // 8

    // same combinations
    OneAndTwo = One | Two,
    OneTwoAndThree = One | Two | Three,
}

Bestätigen Sie mit LinqPad:

foreach(var e in Enum.GetValues(typeof(Options))) {
    string.Format("{0} = {1}", e.ToString(), (byte)e).Dump();
}

Ergebnisse in:

None = 0
One = 1
Two = 2
OneAndTwo = 3
Three = 4
OneTwoAndThree = 7
Four = 8

62voto

In Erweiterung der akzeptierten Antwort können in C#7 die Enum-Flags mit binären Literalen geschrieben werden:

[Flags]
public enum MyColors
{
    None   = 0b0000,
    Yellow = 0b0001,
    Green  = 0b0010,
    Red    = 0b0100,
    Blue   = 0b1000
}

Ich denke, diese Darstellung macht deutlich, wie die Flaggen funktionieren unter der Bettdecke .

54voto

OJ. Punkte 28189

Im Folgenden finden Sie ein Beispiel, das die Erklärung und die mögliche Verwendung zeigt:

namespace Flags
{
    class Program
    {
        [Flags]
        public enum MyFlags : short
        {
            Foo = 0x1,
            Bar = 0x2,
            Baz = 0x4
        }

        static void Main(string[] args)
        {
            MyFlags fooBar = MyFlags.Foo | MyFlags.Bar;

            if ((fooBar & MyFlags.Foo) == MyFlags.Foo)
            {
                Console.WriteLine("Item has Foo flag set");
            }
        }
    }
}

45voto

Keith Punkte 141163

I kürzlich gefragt über etwas Ähnliches.

Wenn Sie Flags verwenden, können Sie eine Erweiterungsmethode zu Enums hinzufügen, um die Überprüfung der enthaltenen Flags zu erleichtern (siehe Beitrag für Details)

Dies ermöglicht es Ihnen zu tun:

[Flags]
public enum PossibleOptions : byte
{
    None = 0,
    OptionOne = 1,
    OptionTwo = 2,
    OptionThree = 4,
    OptionFour = 8,

    //combinations can be in the enum too
    OptionOneAndTwo = OptionOne | OptionTwo,
    OptionOneTwoAndThree = OptionOne | OptionTwo | OptionThree,
    ...
}

Dann können Sie das tun:

PossibleOptions opt = PossibleOptions.OptionOneTwoAndThree 

if( opt.IsSet( PossibleOptions.OptionOne ) ) {
    //optionOne is one of those set
}

Ich finde das einfacher zu lesen als die meisten Möglichkeiten, die enthaltenen Flaggen zu überprüfen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X