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?
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
Die anderen Antworten sind richtig, aber wenn Sie Blau von oben entfernen möchten, würden Sie schreiben:
colors &= ~Blah.BLUE;
And not
es ...............................
Blah.RED | Blah.YELLOW ==
(Blah.RED | Blah.BLUE | Blah.YELLOW) & ~Blah.BLUE;
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;
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;
}
Sie können dies verwenden:
colors &= ~Blah.RED;