Флаги- и не-флаги-вариант перечисления - PullRequest
4 голосов
/ 26 января 2012

Допустим, мне нужно и перечисление как во флаге, так и в варианте без флага.

  • Вариант 1: я мог продублировать все:

    enum Color { Red, Blue, Green }
    
    [Flags]
    enum Colors {
        None = 0,
        Red = 1,
        Blue = 2,
        Green = 4
    }
    
    // use cases
    Color currentColor;
    Colors supportedColors;
    
  • Вариант 2: я мог бы просто использовать вариант Flags для всего:

    Colors currentColor; // ugly, since neither "None" nor "Red | Blue" should be valid
    

Мне не нравится ни один из них: в варианте 1 Color.Red и Colors.Red совершенно не связаны, что может потребовать связующего кода. Кроме того, мне нужно будет синхронизировать два перечисления. Недостаток варианта 2 очевиден. На самом деле мне бы хотелось что-то вроде

enum Colors = Flag set of Color;

Есть ли более изящное решение этого требования?

Ответы [ 4 ]

5 голосов
/ 26 января 2012

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

var flags = (Color)47; // why not

Так что вам нужно проверить, что Color это то, что вы ожидали в любом случае . [Flags] только поможет сериализации / разбора.

2 голосов
/ 26 января 2012

Недавно у меня была такая же проблема. Решено вариантом 2 с простой проверкой:

bool IsColorValid(Color color)
{
    return (color != 0 && (color & (color - 1)) == 0);
}
2 голосов
/ 26 января 2012

Единственный возможный недостаток варианта 2 - нехватка битов.Если это ваша проблема, перечисление флагов вам совсем не подходит.Вместо этого сделайте поддерживаемые цвета HashSet<Color>

1 голос
/ 26 января 2012

Определенно не делайте двух перечислений, называемых Цвет и Цвет (вариант 1). Это сделает ваш код очень запутанным.

Если я что-то упустил, я не думаю, что вариант 2 настолько уродлив. В общем случае разумно инициализировать системный параметр значением по умолчанию «Нет» перед его установкой во время выполнения.

...