Флаги перечисления не добавляют значение

У меня есть несколько проблем с использованием перечисления флагов.

Мое перечисление выглядит следующим образом (я объявил атрибут 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

Что я делаю не так? Я новичок во флагах, поэтому, возможно, я пропускаю какой-то шаг. Большое спасибо!

1 | 3 == 3 так что ваши "Двери" потеряны. | — это побитовое ИЛИ, а не конкатенация
Hans Kesting 16.08.2023 16:30

@HansKefing, стандартные перечисления могут содержать только значение за раз. Перечисления, украшенные атрибутом [Flags] (и использующие степень двойки!), позволяют рассматривать их как битовые маски, хранящие несколько значений. Итак, Категор.Двери | Categ.Rooms не теряет "Двери", как вы предлагаете.

swatsonpicken 16.08.2023 16:49

@swatsonpicken со значениями, которые использовал OP, «двери» теряются, потому что битовая маска 1 (двери) включена в битовую маску 3 (комнаты). Конечно, со степенью двойки этого бы не произошло.

Hans Kesting 16.08.2023 17:37

@ HansKefing, да, ты совершенно прав.

swatsonpicken 16.08.2023 17:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Добавление атрибута [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
}

Другие вопросы по теме