【问题标题】:Best Flag Value to be used (Tips & Good Practice)要使用的最佳标志值(提示和良好实践)
【发布时间】:2013-01-17 16:34:56
【问题描述】:

在学习flag 技术时,我遇到了一些问题,特此我用 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 

(cont') IFF x = {ODD 字节值}


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


参考: Here's the full example.

【问题讨论】:

  • 我认为在这种情况下你应该将其转换为 enum 以进行按位运算
  • 在你的例子中, None 并不是一个真正的标志值(你不能用你拥有的逻辑来检查它)。您看到的 1 的“问题”只是二进制算术中 1 位的定义。
  • 对于 C#,请参阅 System.FlagsAttribute
  • IFF x contains any ODD byte values:当然可以。如果该值为奇数,则将设置第一位,因此设置读取位(根据您的定义)。如果您想知道是否only 设置了读取位,只需将您的值与PermissionTypes.Read 进行比较。如果您想知道是否设置了读取位,无论设置了哪些其他位,请使用& mask = mask 技巧。
  • @Roylee:您的标志值应该是 2 的幂。即1,2,4,8,16,32,... 任何其他值都将是这些标志的组合。例如,您可以创建一个值为 3 的 ReadAndWrite 标志,但这将是 ReadWrite 标志的组合。

标签: c# enums bit-manipulation flags


【解决方案1】:

正如@antlersoft 在 cmets 中所说,您不能真正使用 NONE 作为位标志。
其余的标志是有意义的。您确实需要使用 2 的幂来获得每个标志 1 位。

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

您用 X 的奇数值描述的问题似乎没有意义。仅当设置了位 1 时,该值才会是奇数。如果你一直使用你的标志,那么只有在 READ 为真时才会设置第 1 位。

【讨论】:

  • 是的,None(或0的任何枚举值)不是标志,而是没有任何标志。
  • @OlivierJacot-Descombes 好的,请注意!我会从那时设置的标志值中排除 0 。 :)
  • @Roylee:在枚举中使用 None 和值 0 是一个很好的做法,以便能够清除变量:permission = PermissionTypes.None;。关键是你不能像标志一样测试它。只需测试permission == PermissionTypes.None。并且标志值始终具有值 1, 2, 4, 8, 16, 32 ... 这些是 2 的幂 (2^0 = 1, 2^1 = 2, 2^2 = 4 ...)。它与偶数和奇数无关。
  • @gprasant:没有None 权限。如果没有给予许可,则根本不需要设置标志!只需设置permission = PermissionTypes.None;。这将清除所有标志,从而清除所有权限。 “无”在这里表示“没有任何权限”。
  • 完全正确。 None 的意思是“不是任何其他人”。您不能使用上面的代码测试hasFlag(None)。没有,测试只是(value == None)
【解决方案2】:

x & PermissionTypes.Read 检查是否设置了值 x 的最后一位,这本身没有任何意义,正如您所发现的那样。程序员可以用几种方式解释它:

  • x 具有通过 x = Readx = x | Read 设置的 Read 标志。
  • x 是奇数(或者更准确地说,除以 2^1 时得到余数 1),类似于 x & 3 - 除以 2^2 时的提醒。

代表单个位值的标志通常在您展示的示例中使用。由程序员决定分配给每个标志的含义。

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

[Flags]
enum StrangeFlags : uint {
    Negative = 0x80000000,
}

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

【讨论】:

    猜你喜欢
    • 2015-05-28
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 2015-07-14
    • 1970-01-01
    相关资源
    最近更新 更多