Poniżej mam wyliczenie flag.
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
Nie mogę sprawić, by stwierdzenie if było prawdziwe.
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
if (testItem == FlagTest.Flag1)
{
// Do something,
// however This is never true.
}
Jak mogę to urzeczywistnić?
None
flagi o wartości zerowej. Zobacz msdn.microsoft.com/en-us/library/vstudio/…&
operatora dla porównania,|
jest jak dodatek:1|2=3
,5|2=7
,3&2=2
,7&2=2
,8&2=0
.0
ocenia dofalse
, wszystko inne dotrue
.Odpowiedzi:
W .NET 4 jest nowa metoda Enum.HasFlag . Dzięki temu możesz napisać:
co jest dużo bardziej czytelne, IMO.
Źródło .NET wskazuje, że działa to tak samo, jak zaakceptowana odpowiedź:
źródło
Enum
klasy.(testItem & FlagTest.Flag1)
jest operacją bitową AND.FlagTest.Flag1
jest równoważne001
z wyliczeniem OP. Teraz powiedzmy, żetestItem
ma Flag1 i Flag2 (więc jest bitowa101
):źródło
Dla tych, którzy mają problem z wizualizacją tego, co dzieje się z przyjętym rozwiązaniem (czyli tym),
testItem
(zgodnie z pytaniem) definiuje się jako:Następnie w instrukcji if lewa strona porównania to:
A pełna instrukcja if (która
flag1
daje wartość true, jeśli jest ustawiona wtestItem
),źródło
@ phil-devaney
Zauważ, że z wyjątkiem najprostszych przypadków, Enum.HasFlag niesie znaczny spadek wydajności w porównaniu z ręcznym pisaniem kodu. Rozważ następujący kod:
Ponad 10 milionów iteracji, metoda rozszerzenia HasFlags zajmuje aż 4793 ms, w porównaniu z 27 ms dla standardowej implementacji bitowej.
źródło
(«flag var» & «flag value») != 0
nie działa dla mnie. Warunek zawsze kończy się niepowodzeniem, a mój kompilator (Unity3D's Mono 2.6.5) zgłasza „ostrzeżenie CS0162: wykryto nieosiągalny kod”, gdy jest używany w plikuif (…)
.… = 1, … = 2, … = 4
na wartościach wyliczenia jest krytycznie ważna podczas używania[Flags]
.1
Zakładałem , że rozpocznie on wpisy o godzinie i przejdzie automatycznie o Po2. Zachowanie wygląda spójnie w MS .NET i przestarzałym Mono. Przepraszam, że się tym zajmę.Ustawiłem metodę rozszerzenia, aby to zrobić: pytanie powiązane .
Gruntownie:
Następnie możesz:
Nawiasem mówiąc, konwencja, której używam dla wyliczeń, jest pojedyncza dla standardu, liczba mnoga dla flag. W ten sposób na podstawie nazwy wyliczenia wiesz, czy może on zawierać wiele wartości.
źródło
HasFlag
zamiast tego używać rozszerzenia.Jeszcze jedna rada ... Nigdy nie wykonuj standardowego testu binarnego z flagą, której wartość wynosi "0". Twoje sprawdzenie tej flagi zawsze będzie prawdziwe.
Jeśli binarnie sprawdzisz parametr wejściowy względem FullInfo - otrzymasz:
bPRez zawsze będzie prawdziwe jako WSZYSTKO i 0 zawsze == 0.
Zamiast tego powinieneś po prostu sprawdzić, czy wartość wejścia wynosi 0:
źródło
źródło
W przypadku operacji bitowych należy używać operatorów bitowych.
To powinno załatwić sprawę:
Edycja: Naprawiono mój czek if - wróciłem do moich sposobów C / C ++ (dzięki Ryanowi Farleyowi za wskazanie tego)
źródło
Odnośnie edycji. Nie możesz tego zrobić. Sugeruję zawinięcie tego, co chcesz, do innej klasy (lub metody rozszerzenia), aby zbliżyć się do potrzebnej składni.
to znaczy
źródło
Spróbuj tego:
Zasadniczo twój kod pyta, czy ustawienie obu flag jest tym samym, co ustawienie jednej flagi, co jest oczywiście fałszywe. Powyższy kod pozostawi ustawiony tylko bit Flag1, jeśli w ogóle jest ustawiony, a następnie porównuje ten wynik z Flag1.źródło
nawet bez [Flags] możesz użyć czegoś takiego
lub jeśli masz wyliczenie o wartości zero
źródło