我收到了以下声明
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
}
现在我想设置除“Clear”标志之外的所有标志。我试过这个:
setField(!FlagEnum.Clear);
但我收到以下消息
Operator '!' cannot be applied to perand of type 'BitMask.FlagEnum'
设置标志,例如:
setField(FlagEnum.F1)
工作正常。
所以问题是如何用我的方法设置FlagEnum的所有字段而不是'Clear'字段?或者这是不可能的,我必须实现这个要求。
答案 0 :(得分:3)
在您的特定情况下,FlagEnum.Clear
设置为零,这意味着它不能设置&#34;。您的标志定义如下(缩写为8位):
Clear = 00000000
F1 = 00000001
F2 = 00000010
F3 = 00000100
F4 = 00001000
F5 = 00010000
F6 = 00100000
因此,如果合并F2
,F3
和F5
,则您的值的二进制表示将为00010110
- 它是组合从这三个标志的按位OR获得。
但是,Clear
应该如何添加到那里? Clear
为零,因此将其与值进行或运算不会改变任何内容。相反,只有在未设置其他任何标志的情况下,您的值才会自动Clear
。
如果这不符合您的意图,请先将0x01
分配给Clear
。
通常,您确实可以从flags变量中删除单个值,并且您对否定该标志值的想法是正确的 - 只是在C#中,按位NOT由波形符号表示{{1} })而不是用于逻辑not的感叹号。
因此,~
的反转位模式为F2
。要从11111101
中移除F2
,OR将不会,因为结果为00010110
。相反,否定值必须与先前的标志组合进行AND运算:
11111111
答案 1 :(得分:0)
关注O.R. 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;
}