Powiedzmy, że mam to wyliczenie:
[Flags]
enum Letters
{
A = 1,
B = 2,
C = 4,
AB = A | B,
All = A | B | C,
}
Aby sprawdzić, czy na przykład AB
jest ustawione, mogę to zrobić:
if((letter & Letters.AB) == Letters.AB)
Czy istnieje prostszy sposób sprawdzenia, czy któraś z flag połączonej stałej flagi jest ustawiona niż poniższe?
if((letter & Letters.A) == Letters.A || (letter & Letters.B) == Letters.B)
Czy mógłbyś na przykład zamienić &
coś na coś?
Niezbyt stabilny, jeśli chodzi o takie binarne rzeczy ...
Odpowiedzi:
Jeśli chcesz wiedzieć, czy litera ma którąkolwiek z liter w AB, musisz użyć operatora AND &. Coś jak:
źródło
letter & Letters.AB
. Edytowałem to tam.Letters.None
, zakładam, że mógłbyś zamienić to0
na mniejszy w porównaniu z magiczną liczbą?W .NET 4 można skorzystać z metody Enum.HasFlag :
Przykład wyświetla następujące dane wyjściowe:
źródło
petsInFamily
ma alboPet.Dog || Pet.Cat
?Używam metod rozszerzających, aby pisać takie rzeczy:
Oto kod:
źródło
where T : struct, IConvertible
. Świetny kod inaczej!IsFlagSet(this Enum value, Enum flag)
jest wystarczający.W .NET 4 lub nowszym dostępna jest metoda HasFlag .
źródło
Jeśli możesz użyć .NET 4 lub nowszego, użyj metody HasFlag ()
przykłady
taki sam jak
źródło
bitwise OR
oznacza to, że „oba muszą być ustawione”, a nie żadne?bitwise OR
połączy wartości, więc 1000 | 0010 staje się 1010 lub oba ustawioneJeśli naprawdę cię to denerwuje, możesz napisać taką funkcję:
źródło
return (value & flag) == flag;
nie kompiluje się: „Operator '&' nie może być zastosowany do operandów typu 'T' i 'T'” .Sprawdza, czy ustawione są zarówno A, jak i B, i ignoruje, czy są ustawione inne flagi.
To sprawdza, czy jest zbiór A lub B i ignoruje, czy jakiekolwiek inne flagi są ustawione czy nie.
Można to uprościć, aby:
Oto C dla operacji binarnych; powinno być proste zastosowanie tego do C #:
Nawiasem mówiąc, nazewnictwo zmiennej w przykładzie pytania to pojedyncza „litera”, co może sugerować, że reprezentuje ona tylko jedną literę; przykładowy kod jasno pokazuje, że jest to zestaw możliwych liter i dozwolonych jest wiele wartości, więc rozważ zmianę nazwy zmiennej „litery”.
źródło
anything_and_a
,a_and_or_c_and_anything_else
iboth_ac_and_anything_else
zawsze było prawdziwe? czy coś mi tu brakuje?Co powiesz na
?
źródło
Stworzyłem prostą metodę rozszerzenia, która nie wymaga sprawdzania
Enum
typów:Działa również na wyliczeniach dopuszczających wartość null. Standardowa
HasFlag
metoda nie działa, więc stworzyłem rozszerzenie, które to obejmuje.Prosty test:
Cieszyć się!
źródło
Jest tutaj wiele odpowiedzi, ale myślę, że najbardziej idiomatycznym sposobem na zrobienie tego z Flags byłoby Letters.AB.HasFlag (letter) lub (Letters.A | Letters.B) .HasFlag (letter), jeśli tego nie zrobiłeś już masz Letters.AB. letter.HasFlag (Letters.AB) działa tylko wtedy, gdy ma oba.
źródło
Czy to zadziała dla Ciebie?
Pozdrowienia,
Sebastiaan
źródło
Możesz użyć tej metody rozszerzenia na wyliczeniu dla dowolnego typu wyliczeń:
źródło
źródło
Możesz po prostu sprawdzić, czy wartość nie wynosi zero.
Ale uważałbym, że lepszym rozwiązaniem byłoby wprowadzenie nowej wartości wyliczenia o wartości zero i porównanie z tą wartością wyliczenia (jeśli to możliwe, ponieważ musisz mieć możliwość modyfikowania wyliczenia).
AKTUALIZACJA
Nieprzeczytaj pytania - naprawiono pierwszą sugestię i po prostu zignoruj drugą sugestię.
źródło
Widzę, że istnieją dwa sposoby sprawdzania, czy ustawiany jest dowolny bit.
Aproach A
Działa to tak długo, jak nie masz nic przeciwko sprawdzaniu wszystkich bitów, w tym również niezdefiniowanych!
Aproach B
To sprawdza tylko zdefiniowane bity, o ile Letters.All reprezentuje wszystkie możliwe bity.
Dla określonych bitów (jeden lub więcej zestawów), użyj Aproach B zastępując litery Wszystkie z bitami, które chcesz sprawdzić (patrz poniżej).
źródło
Przepraszam, ale pokażę to w VB :)
CntValue = 5 Więc wyliczenie zawiera 1 + 4
źródło