我们正在重新考虑将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溢出网络中的任何用户。这只是另一个角色
答案 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)
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;)不能应用于枚举值。