非二进制枚举标志

本文关键字:标志 枚举 二进制 | 更新日期: 2023-09-27 18:03:42

在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级的读取权限

除了为每个权限使用不同的位标志(由于非常糟糕的原因,这将要求我的数据库持有比INT大得多的整数(,或者为每个权限拥有不同的枚举(和列((这将限制我使用权限的灵活性(,并且没有任何形式的编译时验证(我想我可以创建某种解决问题的运行时验证(,你还有其他想法吗?

非二进制枚举标志

您的数据库不需要存储大于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、Write等来更好地组织这些。例如,您可以将Read阻塞为前8位,将Write阻塞为后8位,依此类推。这样,您可以适应未来的变化,也可以有效地使用位掩码。