webentwicklung-frage-antwort-db.com.de

Wie entferne ich ein Element für eine OR'd-Enumeration?

Ich habe eine Aufzählung wie:

public enum Blah
{
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16
}

Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;

Wie kann ich die Farbe Blau aus den variablen Farben entfernen?

143
Blankman

Sie müssen es mit dem & (Ergänzung) von 'BLAU' ~.

Der Komplementoperator kehrt im wesentlichen alle Bits für den gegebenen Datentyp um oder "kippt" sie. Wenn Sie den Operator AND (&) mit einem Wert (nennen wir diesen Wert 'X') und dem Komplement eines oder mehrerer gesetzter Bits (nennen wir diese Bits Q und ihr Komplement ~Q) verwenden, wird durch die Anweisung X & ~Q any gelöscht Bits, die in Q von X gesetzt wurden, und geben das Ergebnis zurück.

Um also die BLUE-Bits zu entfernen oder zu löschen, verwenden Sie die folgende Anweisung:

colorsWithoutBlue = colors & ~Blah.BLUE
colors &= ~Blah.BLUE // This one removes the bit from 'colors' itself

Sie können auch mehrere zu löschende Bits wie folgt angeben:

colorsWithoutBlueOrRed = colors & ~(Blah.BLUE | Blah.RED)
colors &= ~(Blah.BLUE | Blah.RED) // This one removes both bits from 'colors' itself

oder alternativ ...

colorsWithoutBlueOrRed = colors & ~Blah.BLUE & ~Blah.RED
colors &= ~Blah.BLUE & ~Blah.RED // This one removes both bits from 'colors' itself

Um es zusammenzufassen:

  • X | Q setzt Bit (s) Q
  • X & ~Q löscht Bit (s) Q
  • ~X kippt/invertiert alle Bits in X
285
SLaks

Die anderen Antworten sind richtig, aber wenn Sie Blau von oben entfernen möchten, würden Sie schreiben:

colors &= ~Blah.BLUE;
40
par

And not es ...............................

Blah.RED | Blah.YELLOW == 
   (Blah.RED | Blah.BLUE | Blah.YELLOW) & ~Blah.BLUE;
8
Daniel A. White

Ich dachte, das könnte für andere Menschen nützlich sein, die hier wie ich stolperten. 

Seien Sie vorsichtig, wie Sie mit Enumerationswerten umgehen, für die Sie möglicherweise einen Wert == 0 festgelegt haben (manchmal kann es hilfreich sein, den Status "Unbekannt" oder "Leerlauf" für eine Enumeration zu haben). Es verursacht Probleme, wenn man sich auf diese Bitmanipulationsoperationen stützt.

Auch wenn Sie Listenwerte haben, die Kombinationen von anderen Potenzen von 2 sind, z. 

public enum Colour
{
    None = 0,  // default value
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16,
    Orange = 18  // Combined value of RED and YELLOW
}

In diesen Fällen kann eine Erweiterungsmethode wie diese hilfreich sein:

public static Colour UnSet(this Colour states, Colour state)
{
    if ((int)states == 0)
        return states;

    if (states == state)
        return Colour.None;

    return states & ~state;
}

Und auch die gleichwertige IsSet-Methode, die die kombinierten Werte verarbeitet (wenn auch etwas hackig)

public static bool IsSet(this Colour states, Colour state)
{
    // By default if not OR'd
    if (states == state)
        return true;

    // Combined: One or more bits need to be set
    if( state == Colour.Orange )
        return 0 != (int)(states & state);

    // Non-combined: all bits need to be set
    return (states & state) == state;
}

Was ist mit xor (^)?

Angenommen, die FLAG, die Sie entfernen möchten, ist vorhanden. Wenn nicht, müssen Sie ein & verwenden.

public enum Colour
{
    None = 0,  // default value
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16,
    Orange = 18  // Combined value of RED and YELLOW
}

colors = (colors ^ Colour.RED) & colors;
2
user4509414

Um die Flag-Aufzählung zu vereinfachen und das Lesen durch Vermeiden von Mehrfachen zu verbessern, können wir die Bitverschiebung verwenden. (Aus einem guten Artikel Ende der großen Debatte über Enum Flags )

[FLAG]
Enum Blah
{
   RED = 1,
   BLUE = 1 << 1,
   GREEN = 1 << 2,
   YELLOW = 1 << 3
}

und auch alle Bits zu löschen

private static void ClearAllBits()
{
    colors = colors & ~colors;
}
0
Matt Allen

Sie können dies verwenden:

colors &= ~Blah.RED; 
0
Majid gharaei