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?

45voto

Jpsy Punkte 18611

Wenn ich mit Flaggen arbeite, deklariere ich oft zusätzliche Elemente None und All. Diese sind hilfreich, um zu prüfen, ob alle Flaggen gesetzt sind oder keine Flagge gesetzt ist.

[Flags] 
enum SuitsFlags { 

    None =     0,

    Spades =   1 << 0, 
    Clubs =    1 << 1, 
    Diamonds = 1 << 2, 
    Hearts =   1 << 3,

    All =      ~(~0 << 4)

}

Verwendung:

Spades | Clubs | Diamonds | Hearts == All  // true
Spades & Clubs == None  // true

 
Update 2019-10:

Seit C# 7.0 können Sie binäre Literale verwenden, die wahrscheinlich intuitiver zu lesen sind:

[Flags] 
enum SuitsFlags { 

    None =     0b0000,

    Spades =   0b0001, 
    Clubs =    0b0010, 
    Diamonds = 0b0100, 
    Hearts =   0b1000,

    All =      0b1111

}

26voto

steve_c Punkte 6051

@Nidonocu

Um eine weitere Markierung zu einem bestehenden Satz von Werten hinzuzufügen, verwenden Sie den Zuweisungsoperator OR.

Mode = Mode.Read;
//Add Mode.Write
Mode |= Mode.Write;
Assert.True(((Mode & Mode.Write) == Mode.Write)
  && ((Mode & Mode.Read) == Mode.Read)));

19voto

David Wengier Punkte 9835

Zum Hinzufügen Mode.Write :

Mode = Mode | Mode.Write;

16voto

Jay Mooney Punkte 2088

Flags ermöglichen Ihnen die Verwendung von Bitmaskierung innerhalb Ihrer Aufzählung. Dadurch können Sie Aufzählungswerte kombinieren, wobei die angegebenen Werte erhalten bleiben.

[Flags]
public enum DashboardItemPresentationProperties : long
{
    None = 0,
    HideCollapse = 1,
    HideDelete = 2,
    HideEdit = 4,
    HideOpenInNewWindow = 8,
    HideResetSource = 16,
    HideMenu = 32
}

16voto

ruffin Punkte 14815

Ich finde es etwas zu langatmig, dass die if ((x & y) == y)... Konstrukt, insbesondere wenn x UND y sind beides zusammengesetzte Sätze von Flaggen und Sie wollen nur wissen, ob es eine jede Überschneidung.

In diesem Fall müssen Sie eigentlich nur Folgendes wissen wenn nach der Bitmaske ein Wert[1] ungleich Null vorhanden ist .

[1] Siehe den Kommentar von Jaime. Wenn wir authentisch wären Bitmaskierung würden wir müssen wir nur prüfen, ob das Ergebnis positiv ist. Aber da enum s kann negativ sein, sogar, seltsamerweise, in Kombination mit die [Flags] Attribut , es ist defensiv zu codieren für != 0 statt > 0 .

Aufbauend auf @andnil's Setup...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BitFlagPlay
{
    class Program
    {
        [Flags]
        public enum MyColor
        {
            Yellow = 0x01,
            Green = 0x02,
            Red = 0x04,
            Blue = 0x08
        }

        static void Main(string[] args)
        {
            var myColor = MyColor.Yellow | MyColor.Blue;
            var acceptableColors = MyColor.Yellow | MyColor.Red;

            Console.WriteLine((myColor & MyColor.Blue) != 0);     // True
            Console.WriteLine((myColor & MyColor.Red) != 0);      // False                
            Console.WriteLine((myColor & acceptableColors) != 0); // True
            // ... though only Yellow is shared.

            Console.WriteLine((myColor & MyColor.Green) != 0);    // Wait a minute... ;^D

            Console.Read();
        }
    }
}

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