[Flags]
Атрибут повинен бути використаний щоразу , коли перелічуваних являє собою набір можливих значень, а не одне значення. Такі колекції часто використовуються з побітними операторами, наприклад:
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
Зауважте, що [Flags]
атрибут не дозволяє це робити сам по собі - все, що він робить, це дозволяє добре представити .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"
Важливо також зауважити, що автоматичні значення перерахунків [Flags]
не роблять двох. Якщо опустити числові значення, перерахунок не буде працювати, як можна було очікувати, в бітових операціях, оскільки за замовчуванням значення починаються з 0 і приросту.
Неправильна заява:
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
Значення, якщо це оголошено таким чином, буде Жовте = 0, Зелене = 1, Червоне = 2, Синє = 3. Це зробить його марним як прапори.
Ось приклад правильної декларації:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
Щоб отримати різні значення у вашій власності, можна зробити це:
if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}
або до .NET 4:
if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}
if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}
Під ковдрами
Це працює, тому що ви використовували сили двох у перерахунку. Під обкладинками ваші значення перерахування виглядають так у двійкових та нулях:
Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000
Аналогічно, після того, як ви встановили для власності AllowedColors червоний, зелений і синій кольори за допомогою |
оператора двійкового бітового АБО , AllowedColors виглядає так:
myProperties.AllowedColors: 00001110
Отже, коли ви отримуєте значення, яке ви насправді виконуєте побіжно ТА &
на значення:
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
Значення None = 0
А щодо використання 0
у вашому перерахуванні цитування з MSDN:
[Flags]
public enum MyColors
{
None = 0,
....
}
Використовуйте None як назву константи, що перераховується у прапорі, значення якої дорівнює нулю. Ви не можете використовувати перелічену константу None в бітовій операції AND для перевірки на прапор, оскільки результат завжди дорівнює нулю. Однак ви можете здійснити логічне, а не побітове порівняння між числовим значенням та переліченою константою None, щоб визначити, чи встановлені будь-які біти числового значення.
Більше інформації про атрибут flags та його використання можна знайти у msdn та проектуванні прапорів у msdn