Dlaczego ludzie zawsze używają wartości wyliczenia, jak 0, 1, 2, 4, 8
lub nie 0, 1, 2, 3, 4
?
Czy ma to coś wspólnego z operacjami bitowymi itp.?
Naprawdę byłbym wdzięczny za mały przykładowy fragment pokazujący, jak to jest poprawnie używane :)
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
c#
permissions
enums
flags
Pascal
źródło
źródło
|
(i&
) reprezentuje. Różne odpowiedzi zakładają, że je znasz.Odpowiedzi:
Ponieważ są one potęgą dwojga i mogę to zrobić:
A może później ...
Jest to pole bitowe, w którym każdy ustawiony bit odpowiada pewnemu zezwoleniu (lub czemukolwiek logicznie odpowiada wyliczona wartość). Gdyby zostały zdefiniowane
1, 2, 3, ...
, nie byłby w stanie używać operatorów bitowych w ten sposób i uzyskać znaczących wyników. Aby zagłębić się głębiej ...Zauważyłeś tutaj wzór? Jeśli weźmiemy mój oryginalny przykład, tj.
Następnie...
Widzieć? Zarówno bity, jak
Read
iWrite
są ustawione i mogę to sprawdzić niezależnie (zauważ również, żeDelete
bit nie jest ustawiony i dlatego ta wartość nie oznacza uprawnień do usuwania).Pozwala na przechowywanie wielu flag w jednym polu bitów.
źródło
myEnum.IsSet
. Jestem zdania, że jest to zupełnie bezużyteczna abstrakcja i służy tylko do ograniczenia pisania, ale mehFlags
atrybut robi niewiele więcej, niż tylko daje „ładny druk” iirc. Możesz użyć wartości wyliczeniowej jako flagi niezależnie od obecności atrybutu.0
nie jestfalse
;false
jestfalse
. Możesz jednak pisaćif((permissions & Permissions.Write) > 0)
.(permissions & Permissions.Write) == Permissions.Write
, możesz teraz użyćenum.HasFlag()
Jeśli nadal nie jest to jasne z innych odpowiedzi, pomyśl o tym w ten sposób:
to tylko krótszy sposób na napisanie:
Istnieje osiem możliwości, ale można je przedstawić jako kombinacje tylko czterech członków. Gdyby istniało szesnaście możliwości, można by je przedstawić jako kombinacje tylko pięciu członków. Gdyby istniały cztery miliardy możliwości, można by je przedstawić jako kombinację tylko 33 członków! Oczywiście o wiele lepiej jest mieć tylko 33 członków, z których każdy (oprócz zera) ma potęgę dwóch, niż próbować nazwać cztery miliardy elementów w wyliczeniu.
źródło
enum
cztery miliardy członków. A smutne jest to, że prawdopodobnie ktoś tego próbował.2 ** -infinity
jako potęgę dwóch).Ponieważ te wartości reprezentują unikalne lokalizacje bitów w systemie binarnym:
itd., więc
EDYTOWAĆ:
3 w systemie dwójkowym jest reprezentowane przez wartość 1 zarówno w miejscu jedynek, jak i dwójek. W rzeczywistości jest taka sama jak wartość
1 | 2
. Więc kiedy próbujesz użyć miejsc binarnych jako flag do reprezentowania jakiegoś stanu, 3 zazwyczaj nie ma znaczenia (chyba że istnieje wartość logiczna, która w rzeczywistości jest kombinacją tych dwóch)Aby uzyskać dalsze wyjaśnienia, możesz chcieć rozszerzyć przykładowe wyliczenie w następujący sposób:
Dlatego w mam
Permissions.All
, ja też pośrednio mająPermissions.Read
,Permissions.Write
iPermissions.Delete
źródło
3
jest11
binarny, tj. Nie mapuje na pojedynczy ustawiony bit, więc tracisz możliwość mapowania 1 bitu w dowolnej pozycji na znaczącą wartość.2|3 == 1|3 == 1|2 == 3
. Więc jeśli mają wartość binarnego00000011
, a twoje flagi włączone wartości1
,2
oraz3
, to nie wiem, czy wartość ta oznacza1 and 3
,2 and 3
,1 and 2
lubonly 3
. To sprawia, że jest o wiele mniej przydatny.Myślę, że pisanie w ten sposób jest łatwiejsze do zrozumienia i czytania i nie musisz tego obliczać.
źródło
Są one używane do reprezentowania flag bitowych, które pozwalają na kombinacje wartości wyliczeniowych. Myślę, że jest to wyraźniejsze, jeśli napiszesz wartości w notacji szesnastkowej
źródło
4194304
przez 2? A co powiesz0x400000
? O wiele łatwiej jest rozpoznać0x800000
poprawną odpowiedź niż8388608
wpisywanie wartości szesnastkowej, a także mniej podatne na błędy.0x10000
potęga dwóch? Tak, zaczyna się od 1, 2, 4 lub 8, a potem ma wszystkie 0. Nie musisz mentalnie tłumaczyć 0x10 na 16 (chociaż prawdopodobnie stanie się to w końcu drugą naturą), po prostu pomyśl o tym jako o „pewnej mocy 2”.To jest bardziej komentarz, ale ponieważ nie obsługuje to formatowania, chciałem po prostu dołączyć metodę, której użyłem do ustawiania wyliczeń flag:
Uważam, że to podejście jest szczególnie pomocne podczas programowania w przypadku, gdy chcesz zachować swoje flagi w porządku alfabetycznym. Jeśli zdecydujesz, że musisz dodać nową wartość flagi, możesz po prostu wstawić ją alfabetycznie, a jedyną wartością, którą musisz zmienić, jest ta, którą teraz poprzedza.
Należy jednak pamiętać, że po opublikowaniu rozwiązania w dowolnym systemie produkcyjnym (zwłaszcza jeśli wyliczenie jest ujawniane bez ścisłego powiązania, na przykład w usłudze sieci Web), zdecydowanie odradza się zmienianie jakiejkolwiek istniejącej wartości w wyliczeniu.
źródło
Wiele dobrych odpowiedzi na to pytanie… powiem tylko… jeśli nie podoba ci się lub nie możesz łatwo pojąć, co
<<
próbuje wyrazić składnia… Osobiście wolę alternatywę (i ośmielę się powiedzieć, prosty styl deklaracji wyliczenia) …LOG 513 == 513
O wiele łatwiejsze (przynajmniej dla mnie) do zrozumienia. Ułóż je w jednej linii… opisz pożądany rezultat, uzyskaj wynik, którego CHCESZ .. Nie są potrzebne żadne „obliczenia”.
źródło