14

我正在尝试新的 HasFlags 功能,并想知道以下是否可行:

enum.HasFlag(AccessRights.Read | AccessRights.Write)

...因为它似乎没有...

 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
  }
4

5 回答 5

34

鉴于文档,如果该值具有这两个标志,我希望它返回 true 。

如果您希望它测试您的值是否具有这些标志中的任何一个,则需要

value.HasFlag(AccessRights.Read) | value.HasFlag(AccessRights.Write)

如果这对你来说不够可读,你可能想看看我的Unconstrained Melody项目。碰巧它已经具有您想要的功能(作为 中的扩展方法Flags.cs):

// Same as value.HasFlag(AccessRights.Read | AccessRights.Write)
value.HasAll(AccessRights.Read | AccessRights.Write)

// Same as value.HasFlag(AccessRights.Read) | value.HasFlag(AccessRights.Write)
value.HasAny(AccessRights.Read | AccessRights.Write)

那些会让事情更清楚,IMO。他们也会避免拳击,并且是类型安全的:)

于 2011-11-02T17:10:12.820 回答
20

来自MSDN

HasFlag 方法返回以下布尔表达式的结果。

thisInstance 和 flag = flag

对于诸如 的复杂标志AccessRights.Read | AccessRights.Write,这将检查是否存在所有“包含”标志。

您可能想检查是否存在任何标志,在这种情况下,您可以执行以下操作:

myAccessRights & (AccessRights.Read | AccessRights.Write) != 0 
于 2011-11-02T17:11:20.970 回答
3

|运算符是按位或。这意味着如果Read是 1 并且Write是 2,则值为Read | Write3(参见其二进制表示)。因此,仅当您的变量同时具有设置时才HasFlag返回 true 。enum ReadWrite

于 2011-11-02T17:10:12.180 回答
1

或者,您可以颠倒表达式的顺序:

//returns true - a bit easier on the eye
(AccessRights.Read | AccessRights.Write).HasFlag(myAccessRights)

如果您有 Read | 这将返回true 写访问。这在功能上等同于:

//also returns true - as per @Ani's answer
myAccessRights & (AccessRights.Read | AccessRights.Write) != 0

编辑

正如评论中所指出的,如果 myAccessRights 为空,则第一个表达式将返回 true,如果 myAccessRights 不仅仅是 Read 和 Write,则返回 false。

于 2015-12-20T23:09:11.210 回答
0

在标记的枚举中,您可以简单地执行以下操作:

(MyEnum01 & MyEnum02) != 0

如果有任何公共位,则将设置一个位,因此该数字不再为 0。如果没有公共位,则结果为 0。为此,标记为 0 的枚举应表示“无”。

这是通用枚举的静态方法和特定枚举的静态方法:

public static partial class UtilityMethods
{
    public static bool HasAnyFlags (Enum enumA, Enum enumB)
    {
        return ((int) (object) enumA & (int) (object) enumB) != 0;
    }

    public static bool HasAnyFlags (MyEnum enumA, MyEnum enumB)
    {
        return (enumA & enumB) != 0;
    }
}

您还可以创建自己的扩展方法:

public static partial class ExtensionMethods
{
    public static bool HasAnyFlag (this Enum e, Enum compared)
    {
        return ((int) (object) e & (int) (object) compared) != 0;
    }
}

对于通用枚举,我从这里进行了转换。据称,使用拳击而不是Converter.ToInt32().

于 2021-10-13T07:03:02.937 回答