2016-08-23 68 views
1

在C#中这是很常见找到以下枚举结构非二进制枚举标志

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

,它允许你加入枚举这样的:Permission.Read|Permission.Create

我现在面对的是一个不同的排序要求,我提出的解决方案是有问题的国际海事组织。

我需要让某种枚举实现多种类型premissions的 - 有些矛盾的,有些是不

,我想下面的排序功能

[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, 

} 

当这亿韩元” t工作Permission.Read1|Permission.Read2主要是因为它意味着用户现在拥有读取权限级别3

除了对每个权限使用不同的位标志(这将需要我的db保存比INT更大的整数,不好的理由),或者每个权限有不同的枚举(和列)(这会限制我的权限灵活性),并且没有编译时验证的形式(我想我可以创建某种工作环境的运行时验证)有没有其他的想法?

+0

它是一种不同类型的权限,或者它是不同的权限对象?即。 Read1在对象类型XXX上读取,在YYY上读取2和Read3 ...等等? – Igor

+0

这个结构主要是为了说明。实际权限调整为不同资源的权限级别,如在Read1..3中为对象xxx,Write1..3为对象YYY – gilmishal

+2

然后您应该更改结构。如果它是一个类型,它将具有2个属性:'PermissionFlags','ObjectType'(对于关系数据库中的表,2列相同)。 ObjectType应该是权限适用的东西。尽可能保持您的权限。我怀疑是否有解决方案可以让你在编译时捕获权限的非法组合,你将不得不在数据库中创建运行时验证和/或添加验证逻辑。 – Igor

回答

1

你的db不需要存储大于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, 

} 

你或许可以通过阻断某些位块为已读这些组织好,写等。例如,您可以阻止读取先前8位被阻塞,然后写入接下来的8位等等等等。这样,您就可以适应未来的变化,并有效地使用位掩码。

+0

尽管它确实限制了一定数量的权限类型,并且由于这是一个新系统,我不能确定它会保持这种状态。由于我可以安全地假设每个动作不会有超过10个权限 - 每个用户只需要一个动作 - 使用多于16位的整数对我来说似乎是浪费 - 即使我可以解决一个32位整数。 – gilmishal