[PL] Flagi bitowe

Za pomocą flag bitowych można wykonywać bitowe operacje na liście wartości stałych. Deklaracja jest podobna do deklaracji zwykłego enuma, jednak należy zwrócić uwagę na dwie rzeczy: Przed deklaracją należy dopisać [Flags], aby zaznaczyć, że będziemy korzystać z flag bitowych. Po drugie każdy element musi być kolejną potęgą liczby 2 (jeżeli tego jawnie nie podamy, każdy kolejny element będzie zwiększany o 1 i przy operacjach bitowych będą występować (naszym zdaniem) błędy), np:

[Flags]
enum Zwierze
{
Zadne = 0,
Pies = 1,
Kot = 2,
Ptak = 4,
Krolik = 8,
Inne = 16
}

W postaci binarnej powyższy przykład przedstawiony jest w następujący sposób:
00000 – Zadne
00001 – Pies
00010 – Kot
00100 – Ptak
01000 – Krolik
10000 – Inne

Można na nim wykonywać operacje bitowe, czyli: OR ( | ), AND ( & ) i XOR ( ^ ). Czyli chcąc wyświetlić wszystkie elementy wpisujemy:

Zwierze zwierze = (Zwierze.Zadne | Zwierze.Pies | Zwierze.Kot | Zwierze.Ptak | Zwierze.Krolik | Zwierze.Inne);
Console.WriteLine(zwierze);

Jednak po wykonaniu nie otrzymamy jednej wartości o nazwie “Zadna”, która przypisana jest pod postać binarną ‘0’, czyli dodając wszystkie wartości za pomocą operatora ‘OR’ otrzymujemy wartość ‘11111’. Ponieważ nie posiadamy takiego elemntu, zostaną wykorzystane po koleji wzorce (1 | 10 | 100 | 1000 | 10000), które dają naszą sumę logiczną. 0 nie zostanie wykorzystane, ponieważ nie ma wpływu na wynik.

Dla przykładu chcąc wyświetlić wartość ‘Kot’ i ‘Królik’, czyli 10 | 1000 otrzymujemy wartość binarną 1010. Więc z wzorca zostają wybrane tylko dwa elementy odpowiadające naszym biotowym wzorcom.

Możemy również usuwać daną flagę z naszego wcześniej już zdeklarowanego schematu, np:

Zwierze zwierze = (Zwierze.Zadne | Zwierze.Pies | Zwierze.Kot | Zwierze.Ptak | Zwierze.Krolik | Zwierze.Inne);
zwierze &= ~Zwierze.Kot;
Console.WriteLine(zwierze);

W powyższym przykładzie zostało najpierw zadeklarowane ‘zwierze’, które wyświetla wszystkie dane, czyli: ‘Pies’, ‘Kot’, ‘Ptak’, ‘Krolik’, ‘Zadne’. Następnie z tego zestawu usuwamy daną ‘Kot’ i wyświetlając ‘zwierze’ otrzymujemy wszystkie dane, oprócz ‘Kot’ (i ‘Zadne’, ale to już wcześniej zostało wyjaśnione).

Wraz z .NET 4.0 została również wprowadzona możliwość sprawdzenia, czy dany element zawiera flagę czy nie. Wystarczy użyć metody HasFlag, np. jak na poniższym przykładzie:

Zwierze zwierze = (Zwierze.Zadne | Zwierze.Pies | Zwierze.Kot | Zwierze.Ptak | Zwierze.Krolik | Zwierze.Inne);
zwierze &= ~Zwierze.Kot;
Console.WriteLine( zwierze.HasFlag(Zwierze.Inne));
Console.WriteLine(zwierze.HasFlag(Zwierze.Kot));

W pierwszym przypadku zwróci nam ‘True’, ponieważ ‘Zwierze.Inne’ posiada flagę. W drugim zaś będzie ‘False’, ponieważ usunelismy flagę z ‘Zwierze.Kot’.

  • Gratuluje podpięcia pod dotnetomaniaka 🙂

  • Gosia Borzęcka

    Dzięki 😉