非二进制枚举标记

时间:2016-08-23 16:29:07

标签: c# enums flags

在c#中,找到以下枚举结构是很常见的

[Flags]
public enum Permission
{
    Read = 1 << 1,
    Create = 1 << 2,
    Update = 1 << 3,
    Destroy = 1 << 4
}

允许您加入这样的枚举:Permission.Read|Permission.Create

我现在面临着不同的要求,我提出的解决方案是有问题的IMO。

我需要允许某种枚举实现多种类型的提交 - 有些矛盾,有些不是

我想要以下类型的功能

[Flags]
public enum Permission
{
    Read1 = 1,
    Read2 = 2,
    Read3 = 3,

    Write1 = 10,
    Write2 = 20,
    Write3 = 30,

    Update1 = 100,
    Update2 = 200,
    Update3 = 300,

    Destory =  1000,

    Other = 10000,

    SomethingElse = 100000,

}

当它不起作用Permission.Read1|Permission.Read2时主要是因为它意味着用户现在具有阅读权限等级3

除了为每个Permission使用不同的位标志(这将要求我的db保存比INT更大的整数),或者每个权限具有不同的枚举(和列)(这将限制我的灵活性)具有权限),并且没有编译时验证的形式(我想我可以创建某种类型的workarroundish运行时验证)你还有其他任何想法吗?

1 个答案:

答案 0 :(得分:1)

您的数据库不需要存储大于int的值。 32位可以为唯一位标志提供更多的值。以下十六进制值是唯一的二进制位标志。 Read1 | Read2不等于Read3

[Flags]
public enum Permission
{
    Read1 = 0x00000001,
    Read2 = 0x00000002,
    Read3 = 0x00000004,

    Write1 = 0x00000008,
    Write2 = 0x00000010,
    Write3 = 0x00000020,

    Update1 = 0x00000040,
    Update2 = 0x00000080,
    Update3 = 0x00000100,

    Destory = 0x00000400,

    Other = 0x00000800,

    SomethingElse = 0x00001000,

}

你可以通过阻止某些位块作为读,写等来更好地组织这些。您可以阻止Read被阻塞前8位,写入接下来的8位等等。这样,您可以适应未来的更改,并有效地使用位屏蔽。