HasFlag для комбинации битовых и однозначных перечислений - PullRequest
1 голос
/ 09 февраля 2012

У меня есть три перечисления, которые - в сочетании - должны идентифицировать уникальное положение дел.

Структура Enums, некоторые битовые поля, другие нет

enum KeyCode
{
    A,
    B,
    C,
    D,
    E
}

[Flags]
enum KeyModifiers
{
    Empty = 0,
    NoModifiers = 10000,
    Shift = 20000,
    Control = 40000,
    Alt = 80000
}

enum KeyState
{
    Empty = 0,
    Down = 10000000,
    Up = 20000000
}

Я хотел бы реализовать класс, который охватывает это состояние и который обеспечил бы метод Contains, который позволил бы мне как-то трактовать комбинацию этих перечислений как одно значение, поддерживающее побитовые операции.

Но текущая реализация не работает, я полагаю, потому что некоторые из базовых перечислений не являются битовыми полями.

Содержит не работает из-за KeyCode

class KeyEvent
{

    public KeyEvent(KeyCode key, KeyState down = KeyState.Empty, KeyModifiers modifiers = KeyModifiers.Empty)
    {
        Key = key;
        State = down;
        Modifiers = modifiers;
    }

    public int Id
    {
        get
        {
            return (int)Key + (int)State + (int)Modifiers;
        }
    }

    public KeyCode Key { get; set; }

    public KeyState State { get; set; }

    public KeyModifiers Modifiers { get; set; }

    public bool Contains(KeyEvent comparable)
    {
        return (Id & comparable.Id) == comparable.Id;
    }

}

Как я мог достичь своей цели, которая заключается в том, чтобы иметь возможность сравнивать текущие значения этих перечислений (this KeyEvent) с входным набором этих значений перечисления (как еще один KeyEvent) так как определить, содержатся ли входные значения в текущем экземпляре (но не обязательно равны ему)?

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Вы должны либо определить KeyCode следующим образом

[Flags]
enum KeyCode {
    A = 1,
    B = 2,
    C = 4,
    D = 8,
    E = 16
} 

, либо рассчитать объединенное значение с помощью

return (int)Math.Pow(2, (int)Key) + (int)State + (int)Modifiers;
1 голос
/ 09 февраля 2012

Ваше KeyCode не является побитовым полем, поэтому использование побитовой логики не имеет смысла. Однако вы можете легко убрать KeyCode и сделать остальное сравнение, как вы показали.

public int StateModifiers { get { return (int)State + (int)Modifiers; } }

public bool Contains(KeyEvent comparable)
{
    return Key == comparable.Key && ((StateModifiers & comparable.StateModifiers) == comparable.StateModifiers);
}
...