У меня есть несколько проблем с использованием перечисления флагов.
Мое перечисление выглядит следующим образом (я объявил атрибут Flags):
[Flags]
public enum Categ
{
None = 0,
Doors = 1,
Views = 2,
Rooms = 3,
Spaces = 4
}
Но когда я пытаюсь использовать его в своем коде, кажется, что вместо добавления последнего значения оно заменяет первое:
var category = Categ.Doors | Categ.Rooms;
//category is always equal to Rooms only
Что я делаю не так? Я новичок во флагах, поэтому, возможно, я пропускаю какой-то шаг. Большое спасибо!
@HansKefing, стандартные перечисления могут содержать только значение за раз. Перечисления, украшенные атрибутом [Flags] (и использующие степень двойки!), позволяют рассматривать их как битовые маски, хранящие несколько значений. Итак, Категор.Двери | Categ.Rooms не теряет "Двери", как вы предлагаете.
@swatsonpicken со значениями, которые использовал OP, «двери» теряются, потому что битовая маска 1 (двери) включена в битовую маску 3 (комнаты). Конечно, со степенью двойки этого бы не произошло.
@ HansKefing, да, ты совершенно прав.





Добавление атрибута [Flags] на самом деле ничего не делает с перечислением, кроме как влияет на то, как работает .ToString(). Вам по-прежнему нужно использовать значения, которые являются степенью двойки для каждого элемента:
[Flags]
public enum Categ
{
None = 0,
Doors = 1,
Views = 2,
Rooms = 4,
Spaces = 8
// then 16, 32, 64 etc.
}
Как указал @DavidG, значения должны быть степенями двойки. Другие варианты, чтобы убедиться, что это...
Чтобы использовать битовый сдвиг:
[Flags]
public enum Categ
{
None = 0,
Doors = 1 << 0,
Views = 1 << 1,
Rooms = 1 << 2,
Spaces = 1 << 3
}
Или, начиная с C# 7.0, использовать двоичные литералы:
[Flags]
public enum Categ
{
None = 0b0000,
Doors = 0b0001,
Views = 0b0010,
Rooms = 0b0100,
Spaces = 0b1000
}
1 | 3 == 3так что ваши "Двери" потеряны.|— это побитовое ИЛИ, а не конкатенация