C# 要使用的最佳标志值(提示和良好实践)

C# 要使用的最佳标志值(提示和良好实践),c#,enums,bit-manipulation,flags,C#,Enums,Bit Manipulation,Flags,在学习标志技术时,我遇到了一些问题,因此我使用C#和Enum展示了这个示例: [Flags] enum PermissionTypes : byte { None = 0x0, Read = 0x1, Write = 0x2, Modify = 0x4, Delete = 0x8, Create = 0x10, All = Read | Write | Modif

在学习
标志
技术时,我遇到了一些问题,因此我使用C#和Enum展示了这个示例:

   [Flags]
    enum PermissionTypes : byte
    {
        None = 0x0,
        Read = 0x1,
        Write = 0x2,
        Modify = 0x4,
        Delete = 0x8,
        Create = 0x10,
        All = Read | Write | Modify | Delete | Create
    }
要检查hasFlag属性,请执行以下操作:

if((value & mask) == mask) {...}
但当“hasFlag”同时应用于“None”和“Read”时:

Denote x = Current_Permission_Setting,

x & PermissionTypes.None = always false
x & PermissionTypes.Read = always true IFF 
(续)IFF x={奇数字节值}


问题:什么是安全使用的完美标志值集


参考资料:
.

正如@antlersoft在评论中所说,您不能真正使用
NONE
作为位标志。
你剩下的旗帜是有意义的。您确实需要使用2的幂才能获得每个标志的1位

无论如何,测试“Has READ and NONE”集合是没有意义的,因为NONE意味着READ未被设置


你用奇数X描述的问题似乎没有意义。如果设置了位1,则该值仅为奇数。如果一致使用标志,则仅当读取为真时才会设置位1。

x&PermissionTypes.READ
检查是否设置了值
x
的最后一位,而这本身并不意味着您发现了什么。程序员可以用几种方式对其进行解释:

  • x
    通过
    x=Read
    x=x | Read
    设置了
    Read
    标志
  • x
    是奇数(或者更准确地说,当除以2^1时给出余数1),类似于
    x&3
    -当除以2^2时的提示
表示单个位值的标志通常在您所展示的示例中使用。它是由程序员来决定什么意义是分配给每个标志

标志用法的另一个示例-通过检查“符号”位检查传入的整数是否为负:


我认为您应该将其转换为enum,以便在本例中执行按位操作。在您的示例中,None不是真正的标志值(您不能使用现有的逻辑进行检查)。对于1,您看到的“问题”只是二进制算术中1位的定义。对于C#,请参见。
IFF x包含任何奇数字节值。
:当然是这样。如果值为奇数,将设置第一位,因此将设置读取位(根据您的定义)。如果您想知道是否只设置了读取位,只需将您的值与
PermissionTypes.read进行比较即可。如果您想知道是否设置了读取位,而不管设置了其他位,请使用
&mask=mask
技巧。@Roylee:您的标志值应该是2的幂。即1,2,4,8,16,32,。。。任何其他值都将是这些标志的组合。例如,您可以创建一个值为3的
ReadAndWrite
标志,但这将是
Read
Write
标志的组合。是的,
None
(或任何
0
的枚举值)不是标志,而是没有任何标志。@OlivierJacot Descombes ok,注意到!我将从设置的标志值中排除0。:)@Roylee:在枚举中使用值为
0
None
是一种很好的做法,以便能够清除变量:
permission=PermissionTypes.None。关键是不能像测试标志一样测试它。只需测试
permission==PermissionTypes.None
。和标志值始终具有值1、2、4、8、16、32。。。这些是二的幂(2^0=1,2^1=2,2^2=4…)。它与偶数和奇数无关。@gprasant:没有
None
权限。如果未授予任何权限,则无需设置任何标志!只需设置
permission=PermissionTypes.None。这将清除所有标志,从而清除所有权限。“无”在这里的意思是“没有任何许可”。“无”的意思是“不包括任何其他人”。您不能使用上面的代码测试hasFlag(无)
。对于none,测试只是
(value==none)
[Flags]
enum StrangeFlags : uint {
    Negative = 0x80000000,
}

int x = -1;
var isNegative = ((StrangeFlags)x & StrangeFlags.Negative) != 0