用于在c#中定义权限集的枚举

时间:2012-04-23 04:47:42

标签: c# .net permissions enums flags

我们正在重新考虑将Flag属性用于Enum以用于逐位操作,而不是将每个权限拆分为单独的列或sql server表。我们的应用程序定义端点(不是来自休息服务的端点)来访问资源(读取,修改,更新),每个用户都有权使用例如Bob has permissions to Read, Modify resource X的权限,所以当bob到来并访问此资源时,我们检查bob是否有许可x。现在我们要申请的地方很明显,这是我的疑惑

  • 假设Bob使用标记枚举对资源有读取,写入,删除权限我会做 Permission.Read | Permission.Write | Permission.Delete 最终结果是按位和整数还是另一个枚举?< / p>

  • 要将此权限存储在数据库表中,该列应为integer吗?

  • 如果对问题1的回答是Enum,那么我应该在Permissions枚举上定义另一个属性,它表示按位和操作的整数值吗?

示例中提到的

disclaimer:不代表网站或任何人的Stack溢出网络中的任何用户。这只是另一个角色

2 个答案:

答案 0 :(得分:10)

按顺序回答您的问题:

  • 假设您已在[Flags]上设置enum属性,并使用正确的运算符(&|进行按位运算),它基本上都是。如果将结果转换为整数,则将获得按位和相关值,即。 7为你的例子。如果您使用.ToString(),则会返回一个字符串,表明该值包含所有三个值。我相信某处有一个HasFlags()方法,但我见过的大多数代码都使用经过验证的真正的按位代码进行比较,即:

    var x = Permissions.Read | Permissions.Write;
    if ((x & Permissions.Read) == Permissions.Read) { print "Success!"; }
    

    从技术角度来看,C#的类型安全性有助于保持理智,|&两个enum相同类型的结果是另一个enum相同类型的所有enum只是整数,在大多数情况下都可以这样处理,尽管有些事情需要显式转换为int

  • 它应该是一个整体类型,是的。我相信枚举的默认类型是Int32,但是如果你想要完全匹配数据库和代码,你可以明确地设置它。

  • 鉴于上述所有情况,为常用的权限集预定义值仍然很有意义,例如ReadWrite。特别是,Microsoft建议所有枚举使用None元素,特别是如果要构建值。这允许新近初始化的变量的回退和有效值以及default(Permissions)的合理值。您可以根据其他类似的值在枚举中设置值:

    [Flags]
    enum Permissions {
      None =    0,
      Read =    0x001,
      Write =   0x010,
      Execute = 0x100,
      ReadWrite = Read | Write,
      // [snip]
    }
    

答案 1 :(得分:5)

  1. 用[Flags]标记的枚举值的按位OR / AND是相同枚举的值。
  2. 整数是合理的归档,用于在数据库中存储枚举值。
  3. 不,您不需要添加额外的枚举值,但可以为客户添加。
  4. Normaly你用FlagsAttribute定义了这样的枚举,即

    [Flags] enum My {
      None = 0, Read =1, Write =2, Delete = 4
    };
    

    以这种方式定义时,您可以将不同的值与|组合使用(或)操作:

    My readAndWrite = My.Read | My.Write;
    

    按位AND将为表示唯一标志的枚举值提供0,但通常用于屏蔽其他位:

    bool doIHaveWrite = (readAndWrite & My.Write) == My.Write;
    

    请注意,逻辑AND(&amp;&amp;)不能应用于枚举值。