• [ Pobierz caÅ‚ość w formacie PDF ]

    Analiza
    Dodanie atrybutu Flags do deklaracji typu wyliczeniowego powoduje, że określone elementy
    typu są traktowane jako indywidualne flagi bitowe, dla których można wykonywać bitową
    operacjÄ™ OR. Zastosowanie typu wyliczeniowego oznaczonego atrybutem Flags niczym nie
    różni się od stosowania standardowego typu wyliczeniowego. Należy zwrócić uwagę, że brak
    oznaczenia typu wyliczeniowego atrybutem Flags nie spowoduje zgłoszenia wyjątku ani
    powstania błędu kompilacji nawet wtedy, gdy elementy typu wyliczeniowego będą wyko-
    rzystane jako flagi bitowe.
    Dodanie atrybutu Flags daje dwie korzyści. Po pierwsze, w przypadku oznaczenia typu
    wyliczeniowego atrybutem Flags metody ToString oraz ToString("G") zwracajÄ… ciÄ…g zna-
    ków składający się z nazw stałych rozdzielonych przecinkami. W innym razie te dwie metody
    zwracają liczbową reprezentację elementu typu wyliczeniowego. Należy zwrócić uwagę, że
    metoda ToString("F") zwraca ciąg znaków składający się z nazw stałych rozdzielonych prze-
    cinkami, niezależnie od tego, czy określony typ wyliczeniowy oznaczono atrybutem Flags
    czy nie. Aby uzyskać wskazówkę dotyczącą sposobu działania tej metody, można zapoznać
    siÄ™ z opisem typu formatowania "F" w tabeli 1.2 zamieszczonej w recepturze 1.16.
    Druga korzyść polega na tym, że w przypadku natknięcia się na typ wyliczeniowy w analizo-
    wanym kodzie, można łatwiej ocenić, do czego programista chciał go wykorzystać. Jeśli jawnie
    zdefiniował go z atrybutem Flags, możemy stosować jego wartości jako maski bitowe.
    Typ wyliczeniowy oznaczony atrybutem Flags można interpretować jako wartość pojedynczą
    lub jako kilka wartości połączonych w jedną. Jeśli chcemy jednocześnie przekazać kilka języków,
    możemy wykorzystać następujący kod:
    Language lang = Language.CSharp | Language.VBNET;
    Zmienna lang jest teraz równa bitowym wartościom dwóch elementów typu wyliczeniowego
    po poddaniu ich operacji OR. W wyniku wykonania tej operacji uzyskamy wartość 3, tak jak
    pokazano poniżej:
    Language.CSharp 0001
    Language.VBNET.....0010
    Po wykonaniu OR 0011
    Elementy typu wyliczeniowego przekształcono na liczby dwójkowe, a następnie wykonano
    operację OR. W jej wyniku uzyskano wartość 0011, czyli 3 w systemie dziesiętnym. Dla kom-
    pilatora ta wartość to zarówno dwa elementy typu wyliczeniowego po wykonaniu operacji OR
    (Language.CSharp | Language.VBNET), jak pojedyncza wartość 3.
    Aby sprawdzić, czy w zmiennej typu wyliczeniowego włączono określoną flagę, można sko-
    rzystać z bitowego operatora AND (&) w następujący sposób:
    Language lang = Language.CSharp | Language.VBNET;
    if((lang & Language.CSharp) == Language.CSharp)
    Console.WriteLine("Zmienna zawiera flagę odpowiadającą językowi C#");
    else
    Console.WriteLine("Zmienna nie zawiera flagi odpowiadającej językowi C#");
    Wykonanie powyższego kodu spowoduje wyświetlenie tekstu Zmienna zawiera flagę odpowia-
    dającą językowi C#. Wykonanie operacji AND dla zmiennej lang i elementu Language.CSharp
    zwróci zero, jeśli w zmiennej lang nie włączono flagi odpowiadającej językowi C#, lub wartość
    1.20. Zastosowanie elementów typu wyliczeniowego w masce bitowej | 53
    Language.CSharp w przypadku, gdy w zmiennej lang włączono tę flagę. Wykonanie operacji
    AND dla dwójkowych reprezentacji obu wartości można zapisać w sposób następujący:
    Language.CSharp | Language.VBNET 0011
    Language.CSharp 0001
    Wynik operacji AND 0001
    Dokładniej problem ten opisano w recepturze 1.21.
    W niektórych przypadkach definicja typu wyliczeniowego rozrasta się do sporych rozmiarów.
    W przypadku typu Language można wprowadzić odpowiedniki wielu różnych języków, tak
    jak pokazano poniżej:
    [Flags]
    enum Language
    {
    CSharp = 0x0001, VBNET = 0x0002, VB6 = 0x0004, Cpp = 0x0008,
    FortranNET = 0x0010, JSharp = 0x0020, MSIL = 0x0080
    }
    Aby utworzyć wartość typu wyliczeniowego Language, która reprezentuje wszystkie języki,
    trzeba by wykonać operację OR dla wszystkich wartości typu:
    Language lang = Language.CSharp | Language.VBNET | Language.VB6;
    Zamiast tego można dodać nową wartość All do typu wyliczeniowego obejmującą wszystkie
    języki. Można to zrobić w następujący sposób:
    [Flags]
    enum Language
    {
    CSharp = 0x0001, VBNET = 0x0002, VB6 = 0x0004, Cpp = 0x0008,
    FortranNET = 0x0010, JSharp = 0x0020, MSIL = 0x0080,
    All = (CSharp | VBNET | VB6 | Cpp | FortranNET | JSharp | MSIL)
    }
    Mamy teraz nową wartość typu wyliczeniowego  All, która obejmuje wszystkie jego wartości.
    Zwróćmy uwagę na to, że istnieją dwa sposoby reprezentacji wszystkich wartości typu wyli-
    czeniowego. Druga z nich jest znacznie bardziej czytelna. Niezależnie od wybranej metody
    w przypadku dodania lub usunięcia elementów typu wyliczeniowego trzeba odpowiednio
    zmodyfikować wartość reprezentującą wszystkie wartości.
    W podobny sposób można wprowadzić wartości odpowiadające określonym podzbiorom
    wartości typu wyliczeniowego, na przykład:
    [Flags]
    enum Language
    {
    CSharp = 0x0001, VBNET = 0x0002, VB6 = 0x0004, Cpp = 0x0008,
    CobolNET = 0x000F, FortranNET = 0x0010, JSharp = 0x0020,
    MSIL = 0x0080,
    All = (CSharp | VBNET | VB6 | Cpp | FortranNET | JSharp | MSIL),
    VBOnly = (VBNET | VB6),
    NonVB = (CSharp | Cpp | FortranNET | JSharp | MSIL)
    }
    Mamy teraz dwa dodatkowe elementy typu wyliczeniowego: jeden odpowiadający wyłącznie
    językom rodziny Visual Basic (Language.VBNET oraz Language.VB6) i drugi, który odpowiada
    innym językom niż VB).
    54 | Rozdział 1. Liczby i typy wyliczeniowe
    1.21. Sprawdzanie, czy ustawiono jednÄ… czy kilka flag
    w danych typu wyliczeniowego
    Problem
    Trzeba sprawdzić, czy w zmiennej typu wyliczeniowego składającej się z flag bitowych włączono
    jedną lub kilka określonych flag. Na przykład dla następującej deklaracji typu wyliczeniowego:
    [Flags]
    enum language
    {
    CSharp = 0x0001, VBNET = 0x0002, VB6 = 0x0004, Cpp = 0x0008
    }
    trzeba sprawdzić, używając logiki Boole a, czy w zmiennej lang zdefiniowanej poniżej włą-
    czono flagi Language.CSharp i (lub) Language.Cpp:
    Language lang = Language.CSharp | Language.VBNET;
    RozwiÄ…zanie
    Aby sprawdzić, czy w zmiennej włączono określoną flagę bitową, można wykorzystać nastę-
    pujÄ…cÄ… instrukcjÄ™ warunkowÄ…:
    if((lang & Language.CSharp) == Language.CSharp)
    {
    // W zmiennej lang włączono co najmniej wartość Language.CSharp.
    }
    Aby sprawdzić, czy w zmiennej włączono wyłącznie określoną flagę bitową, można wyko-
    rzystać następującą instrukcję warunkową:
    if(lang == Language.CSharp)
    {
    // W zmiennej lang włączono tylko wartość Language.CSharp.
    }
    Aby sprawdzić, czy w zmiennej włączono zbiór wszystkich flag bitowych, można skorzystać
    z następującej instrukcji warunkowej:
    if((lang & (Language.CSharp | Language.VBNET)) ==
    (Language.CSharp | Language.VBNET))
    {
    // W zmiennej lang włączono co najmniej elementy Language.CSharp oraz Language.VBNET.
    }
    Aby sprawdzić, czy w zmiennej włączono jedynie zbiór określonych flag bitowych, można
    skorzystać z następującej instrukcji warunkowej:
    if((lang | (Language.CSharp | Language.VBNET)) ==
    (Language.CSharp | Language.VBNET))
    {
    // W zmiennej lang włączono jedynie elementy Language.CSharp oraz Language.VBNET.
    }
    1.21. Sprawdzanie, czy ustawiono jednÄ… czy kilka flag w danych typu wyliczeniowego | 55
    Analiza
    W przypadku typów wyliczeniowych zdefiniowanych jako flagi bitowe z wykorzystaniem
    atrybutu Flags zazwyczaj występuje potrzeba wykonania określonych instrukcji warunkowych.
    Zwykle wykorzystuje siÄ™ w nich operatory bitowe AND (&) oraz OR (|).
    Sprawdzenie, czy w zmiennej ustawiono określone flagi bitowe, można wykonać za pomocą
    następującej instrukcji warunkowej:
    if((lang & Language.CSharp) == Language.CSharp)
    gdzie lang jest zmiennÄ… typu wyliczeniowego Language.
    Operator & w połączeniu z maską bitową wykorzystuje się w celu stwierdzenia, czy określo- [ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • matkadziecka.xlx.pl