【问题标题】:HasFlag for a combination of bitwise and single-value EnumsHasFlag 用于按位和单值枚举的组合
【发布时间】:2012-02-09 17:48:31
【问题描述】:

我有三个枚举,它们 - 组合起来 - 应该确定一个独特的事态。

枚举结构,一些位字段,其他不是

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 方法,这将使我能够以某种方式将这些枚举的组合视为支持按位运算的单个值。 em>

但目前的实现不起作用,我相信是因为一些底层枚举不是位字段。

包含因 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;
    }

}

我怎样才能实现我的目标,即能够将这些枚举(thisKeyEvent)的当前值与这些枚举值的输入集(作为另一个KeyEvent)进行比较,所以至于判断输入值是否包含在当前实例中(但不一定等于)?

【问题讨论】:

    标签: c# .net enums keyboard bit-manipulation


    【解决方案1】:

    您必须像这样定义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;
    

    【讨论】:

    • 我复制粘贴了2^(int)Key,这是一个非常简洁的解决方案,但它没有奏效,可能是因为你的意思是(int)Math.Pow(2, (int)Key) + (int)State + (int)Modifiers; 不幸的是,这在我的情况下也不起作用,因为实际上我在KeyCode 中有超过200 个值,甚至ulongdecimal 都没有足够大的最大值来容纳这样的权力——所以我将不得不使用单独的枚举比较(这本身并不坏)。谢谢!
    • 确实,我指的是权力。 ^ 是 XOR,:-(。当然,每个枚举值都需要一位。
    【解决方案2】:

    您的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);
    }
    

    【讨论】:

    • 谢谢,这就是我现在正在做的事情,但是使用 .NET 4 中可用的 HasFlag 扩展方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多