Atrybutu [Flags]
należy używać zawsze, gdy przeliczalność reprezentuje zbiór możliwych wartości, a nie pojedynczą wartość. Takie kolekcje są często używane z operatorami bitowymi, na przykład:
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
Pamiętaj, że atrybut [Flags]
nie sam tego umożliwia — pozwala jedynie na ładną reprezentację za pomocą metody .ToString()
:
enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
[Flags] enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
...
var str1 = (Suits.Spades | Suits.Diamonds).ToString();
// "5"
var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();
// "Spades, Diamonds"
Należy również zauważyć, że [Flags]
nie automatycznie powoduje, że wartości wyliczeniowe są potęgami dwójki. Jeśli pominiesz wartości liczbowe, wyliczenie nie będzie działać tak, jak można by się spodziewać w operacjach bitowych, ponieważ domyślnie wartości zaczynają się od 0 i są zwiększane.
Nieprawidłowa deklaracja:
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
Wartości zadeklarowane w ten sposób będą następujące: Żółty = 0, Zielony = 1, Czerwony = 2, Niebieski = 3. To sprawi, że będzie ono bezużyteczne jako flagi.
Oto przykład prawidłowej deklaracji:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
Aby pobrać różne wartości w swojej właściwości, można to zrobić:
if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}
lub wcześniej niż .NET 4:
if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}
if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}
Pod kołdrą
Działa to, ponieważ w wyliczeniu użyłeś potęgi dwójki. Pod okładkami wartości wyliczeniowe wyglądają następująco w postaci binarnej i zera:
Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000
Podobnie, gdy ustawisz właściwość AllowedColors na Czerwony, Zielony i Niebieski za pomocą binarnego operatora bitowego OR |
, parametr AllowedColors wygląda następująco:
myProperties.AllowedColors: 00001110
Zatem pobierając wartość, faktycznie wykonujesz bitowe ORAZ &
na wartościach:
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
Wartość Brak = 0
A jeśli chodzi o użycie 0
w twoim wyliczeniu, cytując z MSDN:
[Flags]
public enum MyColors
{
None = 0,
....
}
Użyj Brak jako nazwy stałej wyliczanej flagi, której wartość wynosi zero. Nie można użyć stałej wyliczeniowej None w operacji bitowej AND do sprawdzenia flagi, ponieważ wynik zawsze wynosi zero. Można jednak przeprowadzić logiczne, a nie bitowe porównanie wartości liczbowej z wartością Brak wyliczona stała określająca, czy ustawione są jakiekolwiek bity wartości numerycznej.
Więcej informacji na temat atrybutu flags i jego użycia można znaleźć pod adresem msdn i projektowanie flag w msdn
person
andynil
schedule
12.08.2008
CatAndDog = Cat | Dog
(logiczne LUB zamiast warunkowego), jak sądzę? - person DdW   schedule 12.09.2016