перечисление с FlagsAttributes - PullRequest
3 голосов
/ 10 января 2011

предположим, что у нас есть enum, который имеет FlagsAttribute.

[Flags]
enum CarOptions
{
  Sunroof = 1,
  Spoiler = 2,
  TintedWindow = 4
}

, который можно легко использовать.теперь предположим, что это

[Flags]
enum CarOptions
{
  SunroofElectrical,
  SunroofMechanical,
  Spoiler,
  TintedWindowBlack,
  TintedWindowPurple
}

конечно, это синтаксически неверно.но автомобиль не может иметь механический и электрический люк в крыше одновременно или иметь черный и фиолетовый цвета TintedWindow.
Вопрос: существует ли механизм для реализации перечисления флагов, который не может иметь некоторые атрибуты одновременно?

Ответы [ 4 ]

3 голосов
/ 10 января 2011

Полагаю, вы бы сделали это, используя разные перечисления для люков и TindedWindows.

2 голосов
/ 10 января 2011

Для этого нет встроенного механизма.Перечисления с флагами позволяют объединять любые комбинации элементов.Вам нужно будет выполнить ручную проверку в таком сценарии или создать модель, которая не принимает недопустимые параметры.Есть и другие варианты, но предпочтительный подход, который я бы выбрал, похож на этот:

class CarOptions
{
    public SunroofKind Sunroof { get; set; }
    public SpoilerKind Spoiler { get; set; }
    public TintedWindowKind TintedWindow { get; set; }
    // Note that I split this into two enums - the kind of tinted window
    // (UV-resistant option too maybe?) and color might be different.
    // This is just an example of how such option composition can be done.
    public TintedWindowColor TintedWindowColor { get; set; }

    // In this class, you can also implement additional logic, such as
    // "cannot have spoiler on diesel engine models" and whatever may be required.
}

enum SunroofKind
{
    None,
    Electrical,
    Mechanical
}

enum SpoilerKind
{
    None,
    Standard
}

enum TintedWindowKind
{
    None,
    Standard
}

enum TintedWindowColor
{
    Black,
    Blue
}

Как видите, я полностью избавился от первоначального перечисления.Я не вижу никакой причины использовать такую ​​конструкцию в этом сценарии - комбинации различных переменных, которые также требуют применения логики комбинаций для конкретной области, не являются хорошими кандидатами для перечисления флагов.Опции и логика должны быть заключены в класс (или, возможно, в структуру, в зависимости от того, как он должен использоваться).

Перечисления с флагами полезны только для очень простых и / или специализированных случаев.

1 голос
/ 10 января 2011

Вы можете использовать один бит флагов, чтобы указать присутствующую особую функцию, а другой, чтобы указать «вкус» функции:

[Flags]
enum CarOptions
{
  Sunroof = 1,
  SunroofElectrical = 1,
  SunroofMechanical = 3,
  Spoiler = 4,
  TintedWindow = 8,
  TintedWindowBlack = 8,
  TintedWindowPurple = 24
}

Тогда невозможно объединить оба «вкуса».

1 голос
/ 10 января 2011

У вас есть два варианта, на мой взгляд:

1) Не используйте enum.Используйте другой механизм для настройки параметров, которые входят в комбинации, которые конфликтуют друг с другом.

2) Определите недопустимые комбинации и проверьте их при установке флагов:

[flags]
enum CarOptions
{
  SunroofElectrical = 1,
  SunroofMechanical = 2,
  Spoiler           = 4,
  TintedWindowBlack = 8,
  TintedWindowPurple= 16,
  // bad combos
  BadSunroof        = 3,
  BadWindowColor    = 24
}

CarOptions opt = CarOptions.SunroofElectrical | CarOptions.SunroofMechanical;
if(opt & BadSunroof)
{
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...