C# 应该";或;使用.Net4 Hasflags:enum.HasFlag(AccessRights.Read | AccessRights.Write)
我正在试用新的HasFlags功能,并想知道以下功能是否有效: enum.HasFlag(AccessRights.Read | AccessRights.Write) 。。。因为它似乎不C# 应该";或;使用.Net4 Hasflags:enum.HasFlag(AccessRights.Read | AccessRights.Write),c#,.net-4.0,enums,enum-flags,C#,.net 4.0,Enums,Enum Flags,我正在试用新的HasFlags功能,并想知道以下功能是否有效: enum.HasFlag(AccessRights.Read | AccessRights.Write) 。。。因为它似乎不 DBAccessRights rights = (DBAccessRights)permission.PermissionFlags; if (rights.HasFlag(DBAccessRights.WikiMode)) { // works } if (rights.Ha
DBAccessRights rights = (DBAccessRights)permission.PermissionFlags;
if (rights.HasFlag(DBAccessRights.WikiMode))
{
// works
}
if (rights.HasFlag(DBAccessRights.WikiMode | DBAccessRights.CreateNew))
{
// Doesn't work
}
DBAccessRights flags = DBAccessRights.WikiMode | DBAccessRights.CreateNew;
if (rights.HasFlag(flags))
{
// Doesn't work
}
|
运算符是按位或。这意味着如果Read
为1而Write
为2,则Read | Write
的值为3(参见其二进制表示)。因此,只有当enum
变量同时设置了Read
和Write
时,HasFlag
才会返回true。如果给定的值同时具有这两个标志,我希望返回true
如果您想让它测试您的值是否有这些标志中的任何一个,您需要
value.HasFlag(AccessRights.Read) | value.HasFlag(AccessRights.Write)
如果你读起来不够好,你可以看看我的项目。碰巧它已经具有您想要的功能(作为中的扩展方法):
这会让事情变得更清楚,我想。它们也会避免装箱,并且是类型安全的:)来自:
HasFlag方法返回以下布尔值的结果
表情
thisInstance和flag=flag
对于复杂标志,如AccessRights.Read | AccessRights.Write
,这将检查是否存在所有“包含的”标志
您可能需要检查是否存在任何标志,在这种情况下,您可以执行以下操作:
myAccessRights & (AccessRights.Read | AccessRights.Write) != 0
或者,您可以颠倒表达式的顺序:
//returns true - a bit easier on the eye
(AccessRights.Read | AccessRights.Write).HasFlag(myAccessRights)
如果您具有读写访问权限,则返回true。这在功能上相当于:
//also returns true - as per @Ani's answer
myAccessRights & (AccessRights.Read | AccessRights.Write) != 0
编辑
正如注释中所指出的,如果myAccessRights为空,则第一个表达式将返回true;如果myAccessRights不仅仅具有读写功能,则第一个表达式将返回false。装箱是否解释了文档底部的性能说明?@makerofthings7:可能-很难说清楚。测量框架和我的实现之间的性能差异会很有趣:)@LamonteCristo此方法还必须在取消装箱之前进行类型检查。如果您传递了错误类型的引用,他们希望抛出
ArgumentException
。我想知道拆箱时是否再次进行了类型检查。我们可以检查字节码或C#源代码。如果有,为什么不直接执行(AccessRights.Read | AccessRights.Write).HasFlag(value)?以防任何人想要直接链接到包含HasAll()的文件
方法https://github.com/jskeet/unconstrained-melody/blob/master/UnconstrainedMelody/Flags.cs
。我在接受这个和乔恩·斯基特的答案之间左右为难。这是实现我目标的最佳方式。他的回答解释了我做错了什么。如果myAccessRights没有设置不正确的标志,则返回true。但无论如何。与此类似,除非您假设读写是AccessRights中定义的唯一标志,否则它在功能上是不等价的——即使它是真的,您也不应该这样做。如果myAccessRights设置了除读或写之外的任何标志,则第一个表达式将返回false。
//also returns true - as per @Ani's answer
myAccessRights & (AccessRights.Read | AccessRights.Write) != 0