2

我有以下声明

 private uint mask;
 Action<FlagEnum> setField = new Action<FlagEnum>(x => this.mask = (uint)x);

例如以下枚举:

[Flags]
public enum FlagEnum : uint
{
    Clear = 0x0,
    F1 = 0x1,
    F2 = F1 << 1,
    F3 = F2 << 1,
    F4 = F3 << 1,
    F5 = F4 << 1,
    F6 = F5 << 1
}

现在我想设置除“清除”标志之外的所有标志。我试过这个:

 setField(!FlagEnum.Clear);

但我收到以下消息

Operator '!' cannot be applied to perand of type 'BitMask.FlagEnum'

设置一个标志,例如:

 setField(FlagEnum.F1)

工作正常。

所以问题是如何用我的方法设置 FlagEnum 的所有字段而不是“清除”字段?或者这是不可能的,我必须实现这个要求。

4

2 回答 2

4

在您的特定情况下,FlagEnum.Clear设置为零,这意味着它不能被“设置”。您的标志定义如下(缩短为 8 位):

Clear = 00000000
F1    = 00000001
F2    = 00000010
F3    = 00000100
F4    = 00001000
F5    = 00010000
F6    = 00100000

因此,如果说F2F3F5组合,您的值的二进制表示将是00010110- 它是从这三个标志的按位或获得的组合。

但是,Clear应该如何在那里添加?Clear为零,因此将其与该值进行或运算不会改变任何内容。相反,只有在没有设置其他标志时,您的值才自动为Clear.

如果这不是您想要的,请从分配0x01到开始Clear


通常,您确实可以从 flags 变量中删除单个值,并且您关于否定标志值的想法是正确的 - 就像在 C# 中,按位 NOT 由波浪号 ( ~) 表示,而不是用于逻辑非的感叹号.

所以,倒置的位模式F211111101。要从 中删除F200010110OR 不会做,因为结果是11111111。相反,否定值必须与前面的标志组合进行与运算:

00010110 & 11111101 = 00010100 (F3, F5)
于 2013-02-11T08:25:44.050 回答
0

遵循 OR Mapper 方法,我以这种方式解决了它:

/// <summary>
    /// Operates the specified flag.
    /// </summary>
    /// <param name="flag">The flag.</param>
    /// <param name="operation">The operation.</param>
    public void Operate(FlagEnum flag, OperationEnum operation)
    {
        this.flag = flag;
        switch (operation)
        {
            case OperationEnum.AND:
                operate((x, y) => x & y);
                break;
            case OperationEnum.OR:
                operate((x, y) => x | y);
                break;
            case OperationEnum.XOR:
                operate((x, y) => x ^ y);
                break;
            case OperationEnum.NOT:
                throw new NotImplementedException("The operation 'NOT' is not implemented so far!");
        }
    }

 /// <summary>
    /// Operates the specified operation.
    /// </summary>
    /// <param name="operation">The operation.</param>
    private void operate(Func<uint, uint, uint> operation)
    {
        this.Mask = operation(this.Mask, (uint)this.flag);
    }

    /// <summary>
    /// Clears the mask.
    /// </summary>
    public void ClearMask()
    {
        this.Mask = (uint)FlagEnum.Clear;
    }
于 2013-02-11T14:05:57.473 回答