Kleiner Hinweis: Eine bitweise Aufzählung in C # sollte das Attribut [Flags] darüber haben.
Nyerguds
@ Nyerguds, kannst du erklären, warum es das Attribut bekommen soll?
Ethan
Es bietet eine bessere IntelliSense-Unterstützung beim Debuggen, da unbekannte Aufzählungswerte als Kombinationen vorhandener Werte erkannt werden.
Nyerguds
1
Es bietet auch einen aussagekräftigeren .ToString()Wert. zB RED, BLUE, YELLOWeher als 22.
Sinjai
Antworten:
328
Sie müssen &es mit der ~(Ergänzung) von 'BLAU'.
Der Komplementoperator kehrt im Wesentlichen alle Bits für den gegebenen Datentyp um oder "dreht" sie um. Wenn Sie also den ANDOperator ( &) mit einem Wert (nennen wir diesen Wert 'X') und dem Komplement eines oder mehrerer gesetzter Bits (nennen wir diese Bits Qund deren Komplement ~Q) verwenden, X & ~Qlöscht die Anweisung alle Bits, die gesetzt wurden Qfrom Xund gibt das Ergebnis zurück.
Um die BLUEBits 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
Wenn ich also mehr entfernen wollte, würde ich einfach Folgendes tun: & = ~ Blah.BLUE & ~ Blah.Green?
Blankman
11
Besser istcolors &= ~( Blah.BLUE | Blah.GREEN );
Par
2
Wie ungewöhnlich, ich habe gerade darüber nachgedacht, wie ich das noch einmal machen soll. Vor ungefähr 5 Tagen :) Diese Frage wurde in meinem Posteingang und in meinem Voila aktualisiert!
Blankman
Gute Antwort. Ich denke du meinst jedoch "& =" nicht "= &" in deinen Codebeispielen;)
Dave Jellison
47
Die anderen Antworten sind richtig, aber um Blau von oben zu entfernen, würden Sie schreiben:
Dachte, dies könnte für andere Leute nützlich sein, die hier wie ich gestolpert sind.
Seien Sie vorsichtig, wie Sie mit Aufzählungswerten umgehen, für die Sie möglicherweise den Wert == 0 festgelegt haben (manchmal kann es hilfreich sein, für eine Aufzählung den Status "Unbekannt" oder "Leerlauf" zu verwenden). Es verursacht Probleme, wenn Sie sich auf diese Bitmanipulationsoperationen verlassen.
Auch wenn Sie Aufzählungswerte haben, die Kombinationen aus anderen Potenzen von 2 Werten sind, z
publicenumColour{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 solche Erweiterungsmethode nützlich sein:
publicstaticColourUnSet(thisColour states,Colour state){if((int)states ==0)return states;if(states == state)returnColour.None;return states &~state;}
Und auch die gleichwertige IsSet-Methode, die die kombinierten Werte behandelt (wenn auch etwas hackig)
publicstaticboolIsSet(thisColour states,Colour state){// By default if not OR'dif(states == state)returntrue;// Combined: One or more bits need to be setif( state ==Colour.Orange)return0!=(int)(states & state);// Non-combined: all bits need to be setreturn(states & state)== state;}
Es scheint mir, dass die einfachere Lösung darin besteht, die Verwendung von 0 als Flag zu vermeiden. Ich typischerweise Flagge Aufzählungen wie aufgebaut dies . Ich verstehe nicht, wie Sie von der Angabe eines Status mit dem Wert 0 profitieren. Schließlich geht es darum, dass Sie sich eher mit den programmiererfreundlichen Namen ( Red, Blue, Green) als mit den zugrunde liegenden Werten befassen können , ja?
Sinjai
Ein noneoder unknownoder unsetEintrag mit dem Wert == 0 ist in vielen Fällen eine gute Sache, da Sie nicht immer davon ausgehen können, dass ein bestimmter Wert die Standardeinstellung ist. Wenn Sie beispielsweise nur Rot, Blau und Grün haben, haben Sie Rot als der Standardwert (z. B. der Wert, den die Aufzählung hat, wenn sie erstellt wird oder der Benutzer sie nicht geändert hat?)
Sverrir Sigmundarson
Können Sie nicht einfach Unset = 1 haben und 1, 2, 4, 8als Ihre Werte verwenden? Wenn Sie einen Standardwert benötigen, sind dies die Standardkonstruktoren, oder? Ich mag es, die Dinge aus Gründen der Lesbarkeit so explizit wie möglich zu halten, und mich auf eine Aufzählung zu verlassen, die standardmäßig auf default(int)( 0) gesetzt wird, wenn kein Wert angegeben wird, obwohl dies Informationen sind, die vermutlich jedem Entwickler bekannt sind, ist für meinen Geschmack sowieso zu hinterhältig. Edit: Oh warte, würde Unset = 0 verhindern, dass etwas ist Unset | Blue?
Sinjai
Sie sind in Ihrer Bearbeitung von Sinjai auf dem richtigen Weg. Wenn Sie den nicht festgelegten Wert == 0 beibehalten, werden einige Probleme behoben. Eine ist das, was Sie erwähnt haben, und eine andere ist, wenn Sie alle Enum-Werte deaktiviert haben, dann brauchen Sie keinen Sonderfall für "Unset", wenn es auf Null gesetzt ist. (zB wenn Sie Red & ~Reddann mit Null enden, müssten Sie Code haben, um diesen Fall zu überprüfen und den UnsetWert explizit zuzuweisen )
Sverrir Sigmundarson
Erwischt. Haben Sie es oft mit nicht gesetzten Flags zu tun?
Sinjai
2
Was ist mit xor (^)?
Vorausgesetzt, dass die FLAG, die Sie entfernen möchten, vorhanden ist, funktioniert sie. Wenn nicht, müssen Sie ein & verwenden.
publicenumColour{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 Vielfachen zu verbessern, können wir die Bitverschiebung verwenden. (Aus einem guten Artikel zum Ende der großen Debatte über Enum Flags )
[FLAG]EnumBlah{
RED =1,
BLUE =1<<1,
GREEN =1<<2,
YELLOW =1<<3}
.ToString()
Wert. zBRED, BLUE, YELLOW
eher als22
.Antworten:
Sie müssen
&
es mit der~
(Ergänzung) von 'BLAU'.Der Komplementoperator kehrt im Wesentlichen alle Bits für den gegebenen Datentyp um oder "dreht" sie um. Wenn Sie also den
AND
Operator (&
) mit einem Wert (nennen wir diesen Wert 'X') und dem Komplement eines oder mehrerer gesetzter Bits (nennen wir diese BitsQ
und deren Komplement~Q
) verwenden,X & ~Q
löscht die Anweisung alle Bits, die gesetzt wurdenQ
fromX
und gibt das Ergebnis zurück.Um die
BLUE
Bits zu entfernen oder zu löschen , verwenden Sie die folgende Anweisung:Sie können auch mehrere zu löschende Bits wie folgt angeben:
oder alternativ ...
Um es zusammenzufassen:
X | Q
setzt Bit (s)Q
X & ~Q
löscht Bit (s)Q
~X
kippt / invertiert alle Bits inX
quelle
colors &= ~( Blah.BLUE | Blah.GREEN );
Die anderen Antworten sind richtig, aber um Blau von oben zu entfernen, würden Sie schreiben:
quelle
And not
es...............................quelle
Dachte, dies könnte für andere Leute nützlich sein, die hier wie ich gestolpert sind.
Seien Sie vorsichtig, wie Sie mit Aufzählungswerten umgehen, für die Sie möglicherweise den Wert == 0 festgelegt haben (manchmal kann es hilfreich sein, für eine Aufzählung den Status "Unbekannt" oder "Leerlauf" zu verwenden). Es verursacht Probleme, wenn Sie sich auf diese Bitmanipulationsoperationen verlassen.
Auch wenn Sie Aufzählungswerte haben, die Kombinationen aus anderen Potenzen von 2 Werten sind, z
In diesen Fällen kann eine solche Erweiterungsmethode nützlich sein:
Und auch die gleichwertige IsSet-Methode, die die kombinierten Werte behandelt (wenn auch etwas hackig)
quelle
Red, Blue, Green
) als mit den zugrunde liegenden Werten befassen können , ja?none
oderunknown
oderunset
Eintrag mit dem Wert == 0 ist in vielen Fällen eine gute Sache, da Sie nicht immer davon ausgehen können, dass ein bestimmter Wert die Standardeinstellung ist. Wenn Sie beispielsweise nur Rot, Blau und Grün haben, haben Sie Rot als der Standardwert (z. B. der Wert, den die Aufzählung hat, wenn sie erstellt wird oder der Benutzer sie nicht geändert hat?)1, 2, 4, 8
als Ihre Werte verwenden? Wenn Sie einen Standardwert benötigen, sind dies die Standardkonstruktoren, oder? Ich mag es, die Dinge aus Gründen der Lesbarkeit so explizit wie möglich zu halten, und mich auf eine Aufzählung zu verlassen, die standardmäßig aufdefault(int)
(0
) gesetzt wird, wenn kein Wert angegeben wird, obwohl dies Informationen sind, die vermutlich jedem Entwickler bekannt sind, ist für meinen Geschmack sowieso zu hinterhältig. Edit: Oh warte, würde Unset = 0 verhindern, dass etwas istUnset | Blue
?Red & ~Red
dann mit Null enden, müssten Sie Code haben, um diesen Fall zu überprüfen und denUnset
Wert explizit zuzuweisen )Was ist mit xor (^)?
Vorausgesetzt, dass die FLAG, die Sie entfernen möchten, vorhanden ist, funktioniert sie. Wenn nicht, müssen Sie ein & verwenden.
quelle
Um die Flag-Aufzählung zu vereinfachen und das Lesen durch Vermeiden von Vielfachen zu verbessern, können wir die Bitverschiebung verwenden. (Aus einem guten Artikel zum Ende der großen Debatte über Enum Flags )
und auch alle Bits zu löschen
quelle
Sie können dies verwenden:
quelle