为什么枚举权限通常有0,1,2,4值?

Pas*_*cal 157 c# permissions enums flags

为什么人们总是使用enum值0, 1, 2, 4, 8而不是0, 1, 2, 3, 4

这与位操作等有关吗?

我真的很感激有关如何正确使用它的小样本片段:)

[Flags]
public enum Permissions
{
    None   = 0,
    Read   = 1,
    Write  = 2,
    Delete = 4
}
Run Code Online (Sandbox Code Playgroud)

Ed *_* S. 265

因为他们是两个人的权力,我可以这样做:

var permissions = Permissions.Read | Permissions.Write;
Run Code Online (Sandbox Code Playgroud)

也许以后......

if( (permissions & Permissions.Write) == Permissions.Write )
{
    // we have write access
}
Run Code Online (Sandbox Code Playgroud)

它是一个位字段,其中每个设置位对应于某些权限(或逻辑上对应的枚举值).如果这些被定义为1, 2, 3, ...您将无法以这种方式使用按位运算符并获得有意义的结果.深入研究......

Permissions.Read   == 1 == 00000001
Permissions.Write  == 2 == 00000010
Permissions.Delete == 4 == 00000100
Run Code Online (Sandbox Code Playgroud)

注意这里的模式?现在,如果我们采取我的原始例子,即,

var permissions = Permissions.Read | Permissions.Write;
Run Code Online (Sandbox Code Playgroud)

然后...

permissions == 00000011
Run Code Online (Sandbox Code Playgroud)

看到?无论是ReadWrite位设置,我可以独立检查(另请注意,Delete设置,因此该值不传达权限删除).

它允许在单个字段中存储多个标志.

  • @Andy:实际上,'Flags`属性只不过给你'漂亮的打印'iirc.无论属性是否存在,您都可以使用枚举值作为标志. (3认同)
  • @detly:因为C#中的语句需要一个布尔表达式.`0`不是'假'; `false`是'false`.但是你可以编写`if((permissions&Permissions.Write)> 0)`. (3认同)
  • @Malcolm:确实如此; `myEnum.IsSet`.我认为这是一个完全没用的抽象,只能减少打字,但是meh (2认同)
  • 而不是'棘手'`(权限和Permissions.Write)== Permissions.Write`,你现在可以使用`enum.HasFlag()` (2认同)

Eri*_*ert 145

如果从其他答案中仍然不清楚,请考虑这样:

[Flags] 
public enum Permissions 
{   
   None = 0,   
   Read = 1,     
   Write = 2,   
   Delete = 4 
} 
Run Code Online (Sandbox Code Playgroud)

只是一种较短的写作方式:

public enum Permissions 
{   
    DeleteNoWriteNoReadNo = 0,   // None
    DeleteNoWriteNoReadYes = 1,  // Read
    DeleteNoWriteYesReadNo = 2,  // Write
    DeleteNoWriteYesReadYes = 3, // Read + Write
    DeleteYesWriteNoReadNo = 4,   // Delete
    DeleteYesWriteNoReadYes = 5,  // Read + Delete
    DeleteYesWriteYesReadNo = 6,  // Write + Delete
    DeleteYesWriteYesReadYes = 7, // Read + Write + Delete
} 
Run Code Online (Sandbox Code Playgroud)

有八种可能性,但您可以将它们表示为仅有四个成员的组合.如果有十六种可能性,那么您可以将它们表示为仅五个成员的组合.如果有40亿种可能性,那么你可以将它们表示为只有33个成员的组合!显然,只有33个成员,每个(除了零)的权力为2,而不是试图在枚举中命名40亿个项目.

  • 拥有40亿成员的"enum"的心理形象+1.可悲的是,可能有人试过了. (32认同)
  • @DanielPryden作为Daily WTF的日常读者,我相信它. (23认同)
  • @MichaelKjörling的33个中的一个是0默认值 (5认同)

Chr*_*ain 36

因为这些值表示二进制中的唯一位位置:

1 == binary 00000001
2 == binary 00000010
4 == binary 00000100
Run Code Online (Sandbox Code Playgroud)

等等

1 | 2 == binary 00000011
Run Code Online (Sandbox Code Playgroud)

编辑:

3 == binary 00000011
Run Code Online (Sandbox Code Playgroud)

二元中的3在一个位置和两个位置由值1表示.它实际上与值相同1 | 2.因此,当您尝试使用二进制位置作为标志来表示某个状态时,3通常不会有意义(除非有逻辑值实际上是两者的组合)

有关进一步说明,您可能希望扩展示例枚举,如下所示:

[Flags]
public Enum Permissions
{
  None = 0,   // Binary 0000000
  Read = 1,   // Binary 0000001
  Write = 2,  // Binary 0000010
  Delete = 4, // Binary 0000100
  All = 7,    // Binary 0000111
}
Run Code Online (Sandbox Code Playgroud)

因此,在我有Permissions.All,我也有含蓄Permissions.Read,Permissions.WritePermissions.Delete

  • @Pascal换了另一种方式,`2 | 3 == 1 | 3 == 1 | 2 == 3`.因此,如果你有一个二进制文件'00000011`的值,并且你的标志包含值'1`,`2`和`3`,那么你不知道该值是否代表`1和3`,`2和3 `,`1和2`或'只有3`.这使它变得不那么有用了. (8认同)

Doz*_*zer 9

[Flags]
public Enum Permissions
{
    None   =    0; //0000000
    Read   =    1; //0000001
    Write  = 1<<1; //0000010
    Delete = 1<<2; //0000100
    Blah1  = 1<<3; //0001000
    Blah2  = 1<<4; //0010000
}
Run Code Online (Sandbox Code Playgroud)

我认为这样的写作更容易理解和阅读,你不需要计算它.


Jar*_*Par 5

这些用于表示允许枚举值组合的位标志.如果用十六进制表示法编写值,我认为更清楚

[Flags]
public Enum Permissions
{
  None =  0x00,
  Read =  0x01,
  Write = 0x02,
  Delete= 0x04,
  Blah1 = 0x08,
  Blah2 = 0x10
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你使用十六进制,那么一眼就能看出你的旗帜是否设置正确(即2的幂数)要容易得多."0x10000"是2的幂吗?是的,它从1,2,4或8开始,之后全部为0.你不需要在心理上将0x10翻译成16(尽管这样做最终可能会成为第二种性质),只需将其视为"2的某种力量". (6认同)
  • @Pascal快,当你把'4194304`乘以2时你会得到什么?`0x400000`怎么样?将"0x800000"识别为正确的答案要比"8388608"容易得多,并且输入十六进制值也更不容易出错. (5认同)
  • @Pascal:在这个时候,也许它对您来说更具可读性,但随着您获得使用十六进制查看字节的经验成为第二天性.十六进制中的两个数字映射到一个字节映射到8位(嗯......一个字节通常是8位,但总是如此......但是对于这个例子,可以概括). (4认同)